0

To meet one of my application's needs, I must store an encrypted object in the database. Sometimes, I need to verify whether the user holds the right decryption key without the need to retrieve (decrypt) the stored object, I just need to make sure the user is its original owner.

I've come up with the solution of storing the encrypted object (using say, Fernet) and also its decryption key (hashed, of course) in the same database (maybe even in the same table), so that if I need to verify the ownership of the object I just need to hash the provided password and compare it with the key stored, without having to actually retrieve the encrypted object.

Does this represent any security risk I'm unaware of?

schroeder
  • 123,438
  • 55
  • 284
  • 319
  • 1
    *"... I just need to hash the provided password and compare it with the key stored, ..."* - I'm not sure what you really want to store. The rest of the question suggests that you want to store the hashed decryption key but this sentence suggests that you want to store the hashed password. This kind if implies for me that you want to use a user provided and thus human memorable password directly for encryption instead of using a KDF to derive a stronger key from the password. – Steffen Ullrich May 01 '20 at 14:35
  • Thanks for the feedback, Steffen. You're right, that is what I intended to do. Could you give me some insight on what would be a more appropriate approach for my problem? – Nicolás Villegas May 01 '20 at 15:33
  • 1
    To complement, in the end, I should be able to retrieve (decrypt?) confidential data based on an user-provided password. It occurs to me that I could impose some minimum standards for such passwords. All I have to make sure is that, if data is compromised, is not because of a flawed security design, but rather only because of the user's responsibility, and in this case other user's data are still kept secure. – Nicolás Villegas May 01 '20 at 15:42
  • *"Could you give me some insight on what would be a more appropriate approach for my problem?"* - The password should not directly be used for encryption but a key is derived from it using a [KDF](https://en.wikipedia.org/wiki/Key_derivation_function). – Steffen Ullrich May 01 '20 at 15:49

2 Answers2

3

Storing encryption keys next to encrypted data is always a security risk, even if the encryption keys are hashed.

Now if I understood correctly, the reason for storing the encryption keys is to check that the user can decrypt the data (since the key is hashed, you wouldn't be able to reverse the hash to decrypt the data). But for this purpose you can use an arbitrary piece of data that isn't the encryption key - just store that token and encrypt it with the same key.

Pedro
  • 3,911
  • 11
  • 25
  • Thanks, Pedro. That's something I had not considered before. What should this 'arbitrary piece of data' look like? Is this a common approach? – Nicolás Villegas May 01 '20 at 15:36
  • Ideally a piece of text that you can generate which is unique per user. You could use actual random data but you'd need to store it alongside to verify. Or a checksum of thereof. – Pedro May 01 '20 at 15:39
1

Does this represent any security risk I'm unaware of?

The largest security risk is that if someone compromises the database, they will have both encrypted data and hashed keys, and can mount a brute force attack on the keys. Correspondingly, you must treat these as passwords, and use a strong password hashing algorithm like bcrypt and not a high-performance algorithm like MD5. Many times your DBMS will include primitives for high-performance algorithms but not for strong cryptographic algorithms, so it's an easy trap to fall into.

gowenfawr
  • 71,975
  • 17
  • 161
  • 198