Thanks for responding. Nomen Nescio wrote:
One thing that is unclear in your protocol is whether s, which I think is the same as initialpass, is stored permanently on the server.
Oh, no, that's not what I meant. s is not the same as initialpass, and s is not stored anywhere. The server never knows what s is, and the client only uses it during an authentication and then forgets it.
If so, then when the server receives h(s.r_x), it can do two checks. The check you described is that the hash of this matches the value the client sent previously, h(h(s.r_x)). The other is that the server can construct s.r_x since it knows both of these values, and then compare h(s.r_x) with what the client sent.
This has two problems. First, it makes the sending of h(h(s.r_x)) unnecessary since the server can verify the client's response just using s. And second, s is a sensitive value which if stolen could be used at some later time to impersonate the user.
Right, that would be horribly wrong.
So I will assume that the server doesn't store s, in which case I don't see why it needs to see initialpass in the first place.
It isn't really needed; it's just for setting up an account. The alternative would be for the user to pick s and r_0 and give the sysadmin h(h(s.r_0)) right off the bat. I just thought this would be more convenient.
In that case the protocol basically says, each time you log on you provide a hash value for which you will provide the hash input next time you log on. The purpose of the r_x values is to keep the user from having to save state; he can compute h(h(s.r_y)) and then forget it, because next time he logs on the server will remind him of what r_y is.
Yes, that's the idea.
The main security problem I see is that an eavesdropper sees r_x and h(s.r_x), allowing him to do a dictionary attack on s. You could use a really slow hash function to slow this attack down, but it is a serious vulnerability.
Good point; that is a big flaw. A precomputed dictionary attack won't work, but if a user picks a weak password, guessing it would be feasible. I guess you could also do a dictionary attack against S/Key, but it would take longer since for each trial you would have to compute the, say, 50th hash.
Given that you are using client software to authenticate, I suggest pursuing SPEKE-style password-authenticated key exchange. There are a number of these systems (some patented) which feature immunity to dictionary attacks on the password.
Cool; thanks for the pointer. I hadn't heard of SPEKE before. Dictionary attack immunity is a really nice feature. Cheers, John Bethencourt