1
$\begingroup$

I'm attempting to find a client/server authentication protocol that allows the client and server to authenticate each other when the client doesn't know the server secret but does have a sensitive key derived from the secret.

I would like to use asymmetric certs, but the server in this case is extremely limited in CPU and memory resources, on the order of 16MHz and 32K Ram; but it does have hardware AES support. Speed of the process is critical to the user-experience, but security is paramount.

I was thinking through it and I'd like something like this (The most secure form of each function is implicit):

ClientID (CID): Unique client identifier that ties the token to the client.

Client Token (CT): HMAC(Secret, CID)

Secret (S): A secret that the server knows. The server (or a third party that also knows the key) creates tokens through an offline commissioning process.

Client -> Server
CID, CNonce

Server -> Client (Server derives expected CT with secret and CID)
SNonce, HMAC(CT, CNonce)

Client -> Server
HMAC(CT, SNonce)

This seems to give me a few properties that I need:

  • The client can verify that the server knows the secret because it is able to HMAC CNonce with a derived CT.
  • The server can verify that the client has the token because it can HMAC the SNonce with the CT.
  • Replay attacks are mitigated by the nonces.
  • MITM attacks mitigated because the token is never transmitted.
$\endgroup$
  • 3
    $\begingroup$ If "the client doesn't know a secret" then the server can't authenticate the client by cryptographic means. Your protocol is no exception: you assume CT is known by the client (or its token, which from a cryptographic standpoint is part of the client), and kept secret. $\;$ I fear that the security depends on what AES mode (CBC, CTR..) is used. $\;$ Also, CT = SHA(CID+Secret) is an ad-hoc (but so far unbroken) key derivation function; CT = HMAC(Secret, CID)would be more academic. $\endgroup$ – fgrieu Feb 13 '15 at 17:10
  • $\begingroup$ Well, the client has the token which is derived from the secret and the clientID (which is a fixed hardware identifier). The server can verify that the client has the token, which I suppose could be considered a secret in and of itself as it would be bad if it was exposed to a malicious third party. However, the client can not create tokens because it doesn't know the commissioning secret. $\endgroup$ – joshperry Feb 13 '15 at 17:29
  • $\begingroup$ Also, I'm not necessarily hoping that this specific protocol is viable if someone knows a standard one that is. $\endgroup$ – joshperry Feb 13 '15 at 17:30
  • $\begingroup$ Do you have to use SHA(CID+Secret)? $\;$ $\endgroup$ – user991 Feb 18 '15 at 18:47
  • $\begingroup$ @RickyDemer No, in fact I changed the question just now to instead use HMAC for the operations. $\endgroup$ – joshperry Feb 18 '15 at 18:56
1
+100
$\begingroup$

The general answer is "no, you can't authenticate someone over a wire unless they know some secret information." The only way to authenticate someone is to have them do something that no one else can do. If you're trying to do it by just sending messages between the parties, the only way I can do something that someone else can't is if I know something they don't (whatever I would send is based only on things I know; if they know what I know they could figure out what I would send themselves).

Your scheme isn't quite that, though. You do have a secret on each side; in fact, it's the same secret on each side (i.e. CT). With a shared secret, authentication absolutely becomes possible; when the shared secret is high-entropy (i.e. not derived from a password), it's even better. MACs should be a decent way to achieve this, although I'd be wary of possible pitfalls (one notable one being that an attacker could get whatever he wants MACed by the server, but with a strong MAC this only allows straight replay, and the scheme stops that).

The other part of your scheme is deriving the shared secrets from a server master secret. If the idea of using HMAC with a secret key to derive client tokens is that you don't need to have a master list of client tokens, then that seems like a sensible approach; HMAC should stop an attacker from creating any secret tokens that they don't already know from other sources. TLS uses HMAC as a PRF to produce cryptographic keys from a secret, so it's a perfectly reasonable choice (the way TLS uses it is having a seed and computing HMAC(secret, label+seed), but in your case you don't need a label).

Much depends on what you plan to do after authentication -- if they'll keep communicating, nothing you did prevents an attacker from tampering with the rest of the communication. For instance, an attacker can hold up message 3 and then send it days later. Is this a problem for your protocol? If so, you have to deal with it somehow.

$\endgroup$
  • $\begingroup$ Having nobody able to create a CT, except the parties that hold the master secret is exactly what I am after here. And, yes having the client be able to prove it has a CT created with the master secret in order to do authentication to any number of these "servers" which have no backhaul for maintaining a list of active clients. The mutual authentication is the only communication that will occur, the server only needs the CID to do its thing. Having a reasonably short session timeout on the server side sounds like a very wise plan. $\endgroup$ – joshperry Feb 18 '15 at 23:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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