In the Secure Remote Password Protocol, the verifier must be stored on the server. In the case of a server compromise, an attacker could obtain these verifiers. If nobody reused passwords, this wouldn't be a big deal (as the users' data is probably also compromised). However since people do reuse passwords it seems a good idea to make offline attacks against the password file difficult.

SRP is based off of a cryptographic hash H; part of the cost of an offline attack would be calculating H, so using an expensive hash for this step seems good. However, I am unsure of the suitability of tunably expensive hashing mechanisms (e.g. PBKDF2, bcrypt, scrypt) for this.

  • $\begingroup$ I think the problem would be finding a collision-resistant key-derivation-function, since a $\hspace{1.2 in}$ collision would allow a fake server to test 2 passwords. $\:$ $\endgroup$ – user991 Aug 1 '12 at 2:49
  • $\begingroup$ @RickyDemer, turns out that's not a problem. First, collision-resistance is not a big issue for this particular application. Second, PBKDF2 is already adequately collision-resistant. $\endgroup$ – D.W. Aug 1 '12 at 5:20

RFC 2945 By Tom Wu the SRP inventor uses x = H(s, H(I, ":", p)) where I is the username demonstrating that can do anything you like to the stretch the password such as prefixing the username then hashing it. So stretching the user entered password before putting it into function using PBKDF2 would increase the time taken for a dictionary attack with no effect on the strength of the protocol e.g. x = H(s, PBKDF2(p))

(Edit Note the design document uses x = H(s, p) but the SRP-6a paper linked to from that page uses x = H(s, I, P) so both differ from the RFC.)

Swapping H for PBKDF2 throughout the protocol would slow down the server drastically. With an online dictionary attack you want the attacking client to run slow without it tying up server resources. This suggests only slowing down the x function whilst keeping a good hashing function like SHA256 or better throughout the rest of the protocol. Also as @otus points out in a comment with an offline attack on a captured verifier they don't need to run the full protocol only the steps to generate the verifier. Again this means that there is no benefit to slowing down the full protocol.

Changing the x function to only use the key stretching algorithm with x = PBKDF2(s, p) slows down the server. The purpose of running the key stretching algorithm is to slow down the client so use both H and PBKDF2 by using the RFC function for x but stretching the raw password then passing into the RFC function giving x = H(s, H(I, ":", PBKDF2(p))).

The advantage of that approach is you actually don’t have to change your SRP implementation at all. You simply stretch the password at the point of input then pass the stretched password to your SRP implementation. No changes are required at the server to support stretching. Any brute force attack against a leaked verifier is slowed by stretching.

  • $\begingroup$ That's a good point that only the calculation of x need be slowed down to prevent an offline attack against a weak p given v, which is what I was concerned about. $\endgroup$ – Jason Oct 14 '15 at 2:22
  • $\begingroup$ @Aidenn it's a good idea to AES encrypt the verifier in the database to protect offsite backups from an offline attack. $\endgroup$ – simbo1905 Oct 16 '15 at 16:47

Yes, you can and use a slow hashing function when constructing the verifier. I would recommend using PBKDF2, as it is designed for this purpose.

In fact, Wikipedia says:

$v$ is the host's password verifier, $v = g^x$, $x = H(s,p)$. Using of functions like PBKDF2 instead of $H$ for password hashing is highly recommended.

Thus, you could use $x=\text{PBKDF2}(s,p)$. Alternatively, you could pre-hash the password with PBKDF2, then use the result as your $p$.

  • $\begingroup$ Thanks, do you have a more reliable source than wikipedia for this? In any event prehashing with PBKDF2 is clearly okay, and will only allow a compromise of the account on the single site, not recovery of the cleartext password. $\endgroup$ – Jason Aug 1 '12 at 22:58
  • $\begingroup$ @Aidenn, sorry, no, I don't have any source for this, alas. Sorry about that. (It's a perfectly fair question. I wish I had a better citation or analysis for you!) $\endgroup$ – D.W. Aug 1 '12 at 23:35
  • $\begingroup$ I have tidied up Wikipedia a bit on this topic. $\endgroup$ – simbo1905 Jan 19 '19 at 11:33
  1. There is no reason why you can't, i.e. why H() used for hashing passwords and for the rest of protocol should be the same.

  2. The only thing you pay for that is the speed. Password hash is only generated on the client while you usually want to spare server's CPU time, client's is less important.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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