django-two-factor-auth icon indicating copy to clipboard operation
django-two-factor-auth copied to clipboard

Encrypt secrets in DB

Open vilda opened this issue 10 years ago • 7 comments

A good practice is to encrypt or hash secret keys in DB. I would suggest to implement this. (Enhancement)

While for one-off keys one way hash functions such as scrypt/bcrypt are available, that's not the option for TOTP where the actual key value is needed. Simple encryption where the encryption key is not stored in DB suffice.

Encryption of secret keys is recommended by RFC 6238.

vilda avatar May 26 '15 13:05 vilda

The relevant part in the specification is the following:

We also RECOMMEND storing the keys securely in the validation system, and, more specifically, encrypting them using tamper-resistant hardware encryption and exposing them only when required: for example, the key is decrypted when needed to verify an OTP value, and re-encrypted immediately to limit exposure in the RAM to a short period of time.

The key store MUST be in a secure area, to avoid, as much as possible, direct attack on the validation system and secrets database. Particularly, access to the key material should be limited to programs and processes required by the validation system only.

Hardware encryption cannot be enforced by this package, but the encryption could be implemented.

Bouke avatar May 29 '15 09:05 Bouke

A possible package to perform the encryption would be: https://github.com/pyca/cryptography.

Bouke avatar Jul 29 '17 18:07 Bouke

Another possible package: https://github.com/defrex/django-encrypted-fields

wkschwartz avatar Aug 24 '17 04:08 wkschwartz

I've looked into this and the issue is that this package only stores the PhoneDevice, but not the other Devices, most notably the TOTPDevice. So while we could encrypt some of the fields, we still wouldn't cover all situations.

Bouke avatar Aug 25 '17 06:08 Bouke

Perhaps a more thorough solution would involve django_otp adopting database encryption in a way that this package could inherit?

wkschwartz avatar Aug 25 '17 12:08 wkschwartz

Incidentally, I should probably take back my recommendation of django-encrypted-fields: it's not Python 3 compatible: defrex/django-encrypted-fields#27

wkschwartz avatar Aug 25 '17 13:08 wkschwartz

Encryption doesn't really add any security in this case, unless you have a safe way to store the encryption keys.

One possible solution would be to somehow derive a key from the user's password (you can use Django's pbkdf2 implementation for this, but don't use the stored password hash!) However, looking at django-otp's code this is currently not possible and would be best done in their TOTPDevice implementation.

For now, a better solution is to use a secure store for the keys, something like Vault.

blubber avatar Jan 04 '18 08:01 blubber