So if I got this right from my intense research, the following procedure would be preferrable:

Use the PBKDF2 key derivation function to derive a secret key from the users password on the client side.

Use the derived key, which was generated using PBKDF2 and hash that key with Argon2id on the server side, and store that hash in the database.

What I wonder now is, why do people typically recommend the key derivation function for creating some secret from a password? Could I not just use Argon2id on the client side to hash the password, then pass that hash to the server, and then hash that hash again with Argon2id to generate the final hash for the database?

What is so special about this key derivation? And can I not use Argon2 to derive a secret key as well, similar to PBKDF2?


1 Answer 1


There's nothing special about PBKDF2. It can -- and should -- be replaced with more modern algorithms like Argon2 whenever possible. PBKDF2 is not resistant against brute-force attacks with GPUs and specialized hardware (ASICs).

However, unlike Argon2, PKBDF2 is standardized in the W3C Web Cryptography API and implemented in browsers. For Argon2, there doesn't even seem to be a canonical JavaScript or WebAssembly library, only a couple of GitHub projects which may or may not be production-ready. This is a very good reason for preferring PBKDF2 in this specific case.

Note that client-side hashing is a rather exotic feature which only helps in very specific scenarios. First off, from the server's perspective, the client-side hash is the password. If an attacker can provide the hash, the server will happily log them in. It's not necessary to know the original password. So the client-side hashing doesn't protect the authentication of your application at all. At best, it protects the password itself, which is only relevant if the password has been reused and allows an attacker to gain access to other applications as well (which of course should never happen). And even then the protection is very limited. If an attacker can exploit vulnerabilities in the client-side code, they're likely able to comprise the entire authentication procedure and capture the password before it's hashed. If the server is malicious, then nothing prevents them from disabling the client-side hashing. The only scenario I can think of is that client-side hashing protects reused(!) passwords in the short window when the server has received the password but hasn't hashed it yet.

  • 2
    Client-side hashing can prevent an application from accidentally logging the password.
    – Sjoerd
    Feb 15 at 13:32
  • Yes, that would be an example for the short window between receiving and hashing the password on the server. However, this still only helps protecting other application when the client has made the major mistake of reusing the password. For the current application, the client-side hash is just as useful for attackers as the original password.
    – Ja1024
    Feb 15 at 13:45
  • @Ja1024 thank you, great answer. The only thing that confuses me is the password-based key derivation terminology. Isn't every hashing algorithm that? It just uses some password and creates a kind of hash/key from that. Or how is a key differnet from a hash?
    – shaniag
    Feb 15 at 14:36
  • A key in this context means a key for an encryption algorithm (or some other keyed algorithm like a message authentication code). Since different algorithms have different key lengths, a generic hash algorithm which produces a fixed-length output like SHA-256 is unsuitable for key generation. It's also unsuitable for password hashing due to its high performance. On the other hand, an algorithm originally meant for deriving keys from passwords can also be used for password hashing, because it's computationally expensive by design (to prevent brute-force attacks).
    – Ja1024
    Feb 15 at 15:04
  • @Ja1024 But Argon2 was not originally meant to derive keys from passwords right? Because in your initial answer you say that pbkdf2 should be replaced with more modern algorithms such as Argon2, but if we say the web crypto API standardizes Argon2, would PBKDF2 not still be more suitable if I wanted to first transform the password into a key on the client side and then hash that derived key later on with argon2 on the server? Or is hashing two times with Argon2 more beneficial? So argon2.hash(argon2.hash(value)) Sorry if these comments are stupid, but I find some stuff a bit confusing
    – shaniag
    Feb 15 at 15:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .