The example I'm working on is this:

i store the user password using Argon2 in my database

and then use PBKDF2 to derive an AES key from the user password , and store only the salt used in PBKDF2, i use the output from this function to encrypt some files for the user

my question is this method safe ?

  • 1
    Safe against what?
    – anon
    Jul 12, 2019 at 14:40

1 Answer 1


If you use multiple password hashing algorithms independent of each other to process the same password, then passwords are protected only as well as the weakest algorithm protects them. PBKDF2 is easier to crack than Argon2. An attacker with only a few bytes of ciphertext can then bruteforce passwords, attacking just PBKDF2 and bypassing Argon2.

If you process them sequentially, as in Argon2(PBKDF2(pwd)) or PBKDF2(Argon2(pwd)) then that's not the problem anymore. (As long as you don't use the intermediate hash output for anything else.)

That's still a bad idea. Giving 100% of your CPU time to Argon2 is better than sharing time between the two. Instead of splitting time 50-50, you can use that 50% you're wasting on PBKDF2 to increase one of Argon2's cost parameter.

You could use that extra time to fill more RAM by increasing memory cost. That reduces an attacker's password hash rate by making the hashing harder to parallelize. Increasing the memory cost also increases run time of each Argon2 evaluation for the attacker, further reducing their hash rate.

Or you could use it to increase the time cost. That makes Argon2 do more passes over the memory allocated to it. This reduces an attackers hash rate because each evaluation takes longer. It also helps decrease the effectiveness of a time-memory-tradeoff attack if you're not already using several iterations. (Increasing the memory cost is preferable if you're already using at the recommended number of iterations.)

Argon2 can be used for key derivation just as well as user authentication. If for some reason you can't do that, then derive one master key using Argon2 and hold onto that key in RAM to use for deriving other keys. There are key-based KDFs as well as password-based KDFs. HKDF, for example.

Technically using PBKDF2 with c = 1 (one iteration) is okay to use as a key-based KDF. (Scrypt uses this technique.) There's no security issue if you're only giving 0.00000000000001% of your password-stretching budget to PBKDF.

You must log in to answer this question.