I read previous posts about the topic of how to encrypt data and login with the same password/key, however the concept still seems unclear to me, especially which data it is safe to store in the database.
This great Post advised the following 2 possibilities:
1: You could derive the encryption key from the password with PBKDF2, and then use a normal cryptographic hash (e.g. SHA-256) of the key as the password hash for logging in.
2: Or, if you want to be extra careful, derive both the encryption key and the password hash from an intermediate key derived from the password using PBKDF2.
I created a diagram of my understanding for the second possibility. Do you think that I have gotten it correctly? Can you maybe think of a better way of implementing it?
N.b.
- I replaced PBKDF2 with scrypt here, but the concept is the same.
- Salts are 16 random bytes generated with urandom
UPDATE
I discovered that the PyCryptodomex (Python) library offers a scrypt
function in which I can specify how many hashes/keys I want from a single input key. For example, if I want 2 256bit long output hashes, I can specify that and scrypt
will create a 2 * 256bit = 512bit
key and simply divide it by 2, resulting in 2 256bit long hashes. I can then use one hash for encrypting the data and one for authentication, thus eliminating the need for the second level of scryt
and SHA256
hashing in my previous concept. I created a visual description of the new concept and I'd appreciate your opinion about it :)
Summary Depending on the library and KDF you use, I guess that either concept 1 or concept 2 (which is essentially the same, but more compact) will work.