For the the client and server to prove to each other that they have the same premaster shared key, the original author suggests this:
M = H(A | B | K) --> <-- H(A | M | K)
The RFC 2945 recommends this:
M = H(H(N) XOR H(g) | H(U) | s | A | B | K) --> <-- H(A | M | K)
How many of these concatenations actually increase security? Also, how much freedom do I have to alter it without reducing security? I would imagine that it would be just as secure for to one replace the XOR with concatenation, for example.
- A - public, random every time, determined by the client
- B - public, random every time, determined by the server
- U - private in my implementation, username (salted hash and salt are public)
- s - public, associated with the user account password, determined by server
- N and g - public, constants, determined by programmer
- K - private, random every time, secret key between the server and client
Which definition should I use? The difference between the two is that more public values determined by the server are concatenated into the second hash. Is this actually worthwhile, since any attacker knows
H(N) XOR H(g) | H(U) | s | A | B just as well as
A | B?
EDIT: Uppercase U is actually the username. I was reading it as lowercase. Obviously not big on C#'s case-sensitivity.