I've recently read about the SCRAM authentication protocol. One of the stated design motivations is to support mutual authentication, but how does the client verify that the salt and cost parameters provided by the server are correct?

If the server provides the same salt as for another user it might reveal that they share a password, and if the server provides very low cost parameters then the hash would become easier to crack. This might enable the server to cheat during the mutual authentication, and possibly for a malicious server to gain access to user credentials.

This issue could trivially be solved by letting the client ignore what the server says and use a static cost parameter and a deterministic salt decided by the client, but then we would no longer be following the specification. If we want use the values provided by the server, what is a good way to go about that? There must be a way for the client to verify that these are the same parameters as used during account registration, I just don't seem to be able to find any info on how.

1 Answer 1


The SCRAM protocol assumes that the client and server have already established trust at some point, agreed on the hash parameters (hash/HMAC algorithm, iterations, salt) and securely exchanged the StoredKey and the ServerKey. Both act as shared secrets to allow mutual authentication in subsequent connections.

If the client doesn't trust the server, then it shouldn't create an account in the first place. In this case, SCRAM never comes into play. If the client does trust the server, it's still free to demand different hash parameters in the registration procedure (which isn't defined in SCRAM). For example, it might reject weak hash/HMAC algorithms or a low iteration count. Either the client and server can agree on the parameters, or they have to abort the registration, and SCRAM never comes into play.

In the SCRAM authentication procedure, the client can again reject hash parameters they consider insecure. It's true that the salt cannot easily be checked by itself. However, if the password is so weak that another user has come up with the same one, then it's easy to attack in any case. Salts cannot and aren't supposed to hide weak passwords.

  • No but one of the uses for salts is to make the same password for different accounts have different hash values. And if they already trust each other then there is no need for mutual authentication. Re-authentication should be done if the server doesn't trust the client anymore or if the client doesn't trust the server anymore. If the server is unauthenticated then the client should want to verify that the authentication is done properly, i.e. with the same parameters as when the trust was previously established.
    – n-l-i
    Commented May 19 at 6:38
  • If different users have identical passwords, that means the passwords are easily guessable (because somebody else already has come up with the same password). Salts cannot fix this. The purpose of salts is to prevent the attacker from reusing hash calculations across different accounts, or from using precalculated lookup tables. If you're worried that a man-in-the-middle attacker (so not the server) makes you use a salt they already have a lookup table for, then you can prevent this by storing the original salt and checking the server-provided one against it.
    – Ja1024
    Commented May 19 at 10:17
  • SCRAM is a very simple protocol which only addresses the problems described in the introduction (the authentication information stored on the server shouldn't be sufficient to impersonate the client etc.). If you want stronger authentication, then you'll need a more complex protocol like TLS with mutual authentication (mTLS).
    – Ja1024
    Commented May 19 at 10:25
  • Ah I see, I missed that in the introduction, "The server does not gain the ability to impersonate the client to other servers [...] unless it performs a dictionary attack." This is exactly what I was thinking about and the question about the salt only matters if the server performs an attack on the provided hash, which is apparently not in the scope of the protocol.
    – n-l-i
    Commented May 19 at 10:34

You must log in to answer this question.

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