I am looking for an Authentication protocol for access control. Let's say both the client and server would share a symmetric secret (256 bit key) and the client wants to access the server. Access should only be granted to a registered client the server shares a key with and both parties should know whom they've talked to.
It should provide:
- mutual authentication (client and server are both sure to talk to server resp. client)
- freshness property to encounter replay attacks
- efficiency: both parties should only have to execute a few cheap computations
- the authentication token should change for every authentication attempt
- the server should be prone (as much as possible) against DoS-attacks
- no replay or pre-play attacks
I couldn't find any protocol like this except Janson-Tsudik's 2PKDP which is patented. Thus, I had the idea to construct an own protocol from the protocols I have seen so far. I know this is probably the worst idea, especially because I am not a professional cryptographer.
But nevertheless I want to share my idea to know the pros and cons. I like the idea about Lamport's hash chains and want to use their hash values as one time authentication tokens (tickets). The advantages are mainly that the verification is really fast (just a hash-function) and the client needs to bring some information not yet known into the server. Unfortunately the major disadvantage is that the client has to precompute all N tickets. Thus I looked up one-way permutations with a trapdoor like for instance chameleon hash functions to be able to go in both directions of the hash chain (also known as infinite, re-initializable or renewable hash chains). Since I couldn't find any good implementation for such a function, I thought about just using RSA signatures: Client has a private key and the server his authenticated (beforehand) public key. The client initially generates a pseudorandom seed value which is then encrypted with the RSA private key (d, N), resulting in my first authentication ticket. Given that the server has also received the initial seed value, it can then upon receiving the first ticket check it by verifying it, i.e. decrypting it with the RSA public key. If the knowledge of the new ticket refers to being granted access, the open problems are how to accomplish mututal authentication and freshness and how to securely transmit the newly generated ticket to the server each time you log in. So far, I thought about something like:
- client sends its client_id to server
- server generates nonce N and sends it back
- client calculates HMAC_T(N, client_id) xor T_new (where T is the last ticket and T_new the new one - and T is used as key for the hash-keyed MAC function)
- server can compute the HMAC_T(N, client_id) since the old T is still available
- server can thus deduce T_new
- server can verify T_new by calculating: RSA_verify(T_new, (e, N)) == T (or in other words: decrypting T_new with the client's public RSA key and check if that yields in T.
Please note that the server needs to keep the last ticket saved because it's used for verifying the one handed with the next authentication request.
Please tell me in a merciless way which problems you see about it and where I haven't thought it through enough. Also if there is already a protocol/scheme that does what I want to, please point me into the right direction.