3
$\begingroup$

I currently use Argon2 to derive a key (I will use a salt which I will save in a file as plaintext for when I later need to derive a key again) from a given password which I will use to encrypt a file (Algorithm: AES CBC PKCS7Padding).

When a user enters the password I need to verify it is the correct password, storing the key or the password will of course break the encryption (since if it's the key they can just decrypt, if it's the password they can derive the key again)

So from what I can see I have 2 options

  1. Use Argon2 as a hash function instead of a KDF function and store the result (I will change the salt between the 2 Argon2 invocations), you can probably guess this will be very slow.
  2. Hash the key with SHA-256

To verify I will just re-hash with either option 1 or option 2 and check if it matches.

Questions

  1. Would option 2 achieve the same security as would option 1?
  2. If I use option 2, for the salt, should I use a new generated salt specifically for that (which I will store in a file as plaintext for later verifications) or use the salt I used with the initial Argon2 KDF or use no salt?
$\endgroup$
4
  • $\begingroup$ This would be fine. In any cryptosystem where the password hash isn't saved, you need to save the salt to get the same hash back. $\endgroup$
    – Jacob H
    Jun 2, 2019 at 18:57
  • $\begingroup$ Please explain what exactly you do. What you mean by "Before decryption"? When you use Argon2, you cannot restore the original password, i.e. you cannot decrypt anything. What you mean by "verify I have derived the correct key"? The word correct is not applicable for the derived key. There are no correct or incorrect keys. May be you mean that you check if the derived key for provided password is the same as the derived key for the correct password? If you use key derivation, there is no place for AES. If you use encryption, there is no place for Argon2. I suppose you compose different met $\endgroup$
    – mentallurg
    Jun 2, 2019 at 21:12
  • $\begingroup$ To be clear, you're thinking to store SHA2(key) along with the ciphertext, and verify that before you attempt decryption? $\endgroup$ Jun 6, 2019 at 15:04
  • $\begingroup$ @SAIPeregrinus Mostly true, I will be storing the salt and a SHA2(key) in 1 file and the ciphertext in another file $\endgroup$ Jun 7, 2019 at 4:22

2 Answers 2

4
$\begingroup$

Running Argon2 (or any other key-stretching KDF) twice to generate two different keys (or other outputs) from the same password is not a good idea, since it makes key derivation twice as slow while not making the password any harder to crack by brute force. Or, in other words, it makes the password twice as fast to crack compared to just running the KDF once with twice as many iterations.

Hashing the key with a secure cryptographic hash, such as SHA-256, and storing the hash alongside the encrypted data is a perfectly good and secure way to implement a key check value. You don't even need to store the entire hash; just, say, the first 32 or 64 bits of the hash should be plenty to catch any accidentally mistyped passwords.

Alternatively, you could use the Argon2 output as the input to a fast non-password-based KDF such as HKDF-Expand and use it to derive both the encryption key and a separate check value. This is a general solution that will work whenever you want to derive multiple quasi-independent keys (or check values etc.) from the same password. In particular, this method provides a stronger guarantee of independence than your suggestion of hashing the key: not only can the key not be calculated from the check value, but (assuming the the underlying hash function is not very badly broken) the check value also cannot be calculated from the key.

$\endgroup$
1
$\begingroup$

Either option would let you verify that the key generated for decryption is the same as the key that was used for encryption.

Neither option lets you verify that the ciphertext being decrypted is the same as the ciphertext that was encrypted, or that the resulting plaintext is the same as the original input.

So neither option adds any security under the usual definitions. Thus for question 1 the answer is that they're identical, and for question 2 it doesn't matter.

$\endgroup$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.