I'm comparing the Wikipedia description of SRP to the BouncyCastle implementation and some differences and I want to be sure the BouncyCastle implementation is suitable for my purpose.

Wikipedia article: https://en.wikipedia.org/wiki/Secure_Remote_Password_protocol

The article has a a description of how M1 and M2 are calculated:

M1 = H[H(N) XOR H(g) | H(I) | s | A | B | K_Carol] M2 = H(A | M1 | K_Steve)

Note that M1 is a rather elaborate calculation involving XOR'ing the hash of N and g, as well as including a hash of "I" inside the outer M1-hash etc. I always wondered about this strange occurence of XOR'ing etc. - it is probably OK but why not just N or g directly in the hash calculation, since all other calculations in the protocol are based around hash (not XOR) and it is going to be a constant anyway. Further, protocol even previously calculates k = H(N,g), which is exactly a hash of N and g, so it is strange why this could not be used here.

But the article also offers an alternative: "Alternatively, in a password-only proof the calculation of K can be skipped and the shared S proven with:

M1 = H(A | B | S) M2 = H(A | M1 | S)

Notable differences is that M1 doesn't include N and g at all (and so not the strange XOR expression). There are also other differences - the hash of I is not included either and instead of using K in the calculation (with K = hash(S)), S is used directly in this case.

In my case I need not just to prove knowledge of the password but also to end up with an encryption key the client can use to submit sensitive data (in the successful case). I would prefer to use BouncyCastle. BouncyCastle seems to implement it as the simplified password-proof only case, and then returns the session key as K = H(S).

Note that the constructions are also different with respect to how K and S is used. Wikipedia has M1 = H(A | B | K) and M2 = H(A | M1 | K) (again where K = H(S)) whereas in BouncyCastle has M1 = H(A | B | S) and M2 = H(A | M1 | S) and then releases K = H(S) as the session key to be used for encryption/decryption after authentication.

My question is basically: Is the BouncyCastle approach safe in this situation (using the protocol to prove mutual knowledge of the password and, if successful, using the resulting session key for sending data), despite the fact the BouncyCastle implementation seems to follow the case Wikipedia refers to as password-proof only (and doesn't have all the XOR goo etc.).


1 Answer 1


Well, there are other implications of the current BouncyCastle implementation, making it unusable unless you use BouncyCastle on both the client and the server. I was just debugging my SRP in HomeKit, trying to figure out why my code that looked perfectly fine did not work. First, I tried to write a BouncyCastle-based client and of course then the SRP worked as expected. However, iOS client was still sending me M1 that I was not able to verify using BouncyCastle. It turned out BouncyCastle calculates the M1 differently (as you've correctly found out) and from that point onwards it cannot be used because the protocol implemented there is incorrect. I was able to use BouncyCastle to calculate B and S, but then I had to calculate M1, M2 and K myself.


Your Answer

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

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