...
AWS' KMS service seems to be the only established externally hosted service for storing secrets. However, its current APIs do not really provide a way for us to store arbitrary keys/credentials. Its CreateKey endpoint does have a way to insert raw-key-material. However, that is only for creating Master Keys, which cannot be later exported. We can use its service to encrypt arbitrary data but then still have to manage the storage ourselves - which doesn't seem to be a worthwhile effortsatisfy the legal concerns.
AWS KMS | |
---|---|
Company | Amazon |
Storage of user data | Stores only user-provided master keys |
Storage/generation of keys | Generates data-encryption keys only |
API | Limited API |
Key Versioning | ? |
Encryption as a service | |
Auditing | Keeps track of key usages |
On-disk encryption (on backend servers) | |
Revocation | |
Cost | ? |
Open Source |
...
- django-fernet-fields (recommended)
- uses pyca/cryptography open source library
- 136 contributors, relatively active, maintained
- Fernet algorithm
- AES with CBC mode, with PKCS7 padding, and SHA256 HMAC Generates base-64 encoded, 32-bit keysymmetric key encryption scheme
- uses pyca/cryptography open source library
- very easy-to-use extension on top of django fields
- readable/understandable code
- can provide custom master key, rather than relying on a single SERVER_KEY
- allows for key rotation of the master key by listing older keys for decryption
- only 5 contributors; now just in maintenance mode (upgrading libraries)
- uses Google's keyczar open source library, which has known security issues, but may not apply to our usage of it
- code is somewhat cryptic - mostly due to keyczar's interface
- 327 contributors, active overall development
- uses Google's keyczar open source library, which has known security issues, but may not apply to our usage of it
Recommended Solution
- Use django-fernet-fields, which uses Fernet
- Fernet essentially combines the latest industrial strength of crypto algorithms for symmetric encryption (so we don't need to pick and choose):
- AES cipher in CBC mode, for encryption
- SHA256 HMAC, for integrity protection
- AES base64-encoded, 32-bit key generation
- Fernet essentially combines the latest industrial strength of crypto algorithms for symmetric encryption (so we don't need to pick and choose):
- django Settings:
- In public env file:
- FERNET_USE_HKDF=True
- In secure auth file (configure FERNET_KEYS, rather than having it use SECRET_KEY)
- FERNET_KEYS=[<current_key>, <older keys>]
- In public env file:
- See Usage section for how to use these in your django models to create encrypted fields automatically
- Code reference: