This is a proposal to accelerate a new authentication option to strengthen the security on the wire and remove the liability of storing passwords on the server. It is based on a typical zero-knowledge auth process: an authentication system where the credentials are never stored on the server or transferred over the wire, but the server is still able to validate the credentials of the client. It depends on the client being able to set-up a one-time-only trusted secret over a secure method beforehand.
The server must store three peices of data: token, hash, sequence#. The client needs the original user password. All digest operations are SHA1
Start with the figurative server data: "garbagerandom", 21e89932a96ec55d96aecf9975, 462. Client performs a digest(password) resulting in hashA, and retrieves the token "garbagerandom" and sequence 462 from the server. The client then performs another digest(hashA + token) resulting in hash0, and then performs 461 recursive digest calls resulting in hash461. The client then sends hash461 to the server.
The server receives hash461 from the client, and performs an additional hash to result in hash462, and compares it to the stored hash for that sequence#. If they match, store the hash461 from the now authenticated client as the new hash and reduce the sequence#.
If the sequence# reaches 0, authentication can no longer occur and a reset is required. A Reset is when the server is given the base hash (hash0 above) and a new unique token, so that it can perform X recursive digests and store the result as the hash and the number of times as the sequence. The authentication is secure, but the reset is not, if the reset happens over an insecure transport layer then the authentication can be falsified based on the data snooped from the reset. The server could optionally perform a very large number of digests, to reduce the time between the required resets. If the user already utilizes an existing system, such as https:// for account maintainence or ssh for system access, the reset could happen on the server side when those methods are used, so that resets securely happen transparently to the user.
<iq type="get" id="100001"> <query xmlns="jabber:iq:auth"> <username>hamlet</username> </query> </iq> <iq type="result" id="100001"> <query xmlns="jabber:iq:auth"> <password/> <digest/> <token>3A58102B</token> <sequence>461</sequence> <resource/> </query> </iq>
This example shows a server that supports plaintext, simple sha1 digest, or zero-knowledge authentication methods. Typically a server is only going to support one of the three, a client should choose the most secure by default. The username is sent in the get to identify to the server which account it should return the auth requirements from. The client then returns the hash for the zero-knowledge method in a set to authenticate.
<iq type="set" id="100002"> <query xmlns="jabber:iq:auth"> <username>hamlet</username> <hash>hash461</hash> <resource>Castle</resource> </query> </iq> <iq type="result" id="100002"/>