views:

48

answers:

2

Our clients call our web service over SSL and authenticate themselves with a username and password. Our server then generates a symmetric key and sends it back to the client.

Then, the client establishes a TCP connection to our server, and sends a login message. At this point, I want to authenticate the client.

My idea is to have the client encrypt a well-known/static piece of text with the symmetric key and use this as proof that it is in possession of the key.

Since the symmetric key is generated randomly, is it ok that I use a static piece of text here?

Any input appreciated.

+2  A: 

SSL is built to authenticate both client and server, and asymmetric cryptography the most secure primitive you can use in this scenario. Symmetric ciphers can be used for authentication by using a Cipher Block Chaining Message Authentication Code other wise known as CBC-MAC mode. The use of CBC-MAC has similar protection as an HMAC, but utilizing a symmetric cipher instead of a message digest function. CBC-MAC mode is used by WPA to protect wireless networks.

Rook
Thanks for your response. I am using .NET 2.0, and it looks like CBC-MAC is only supported from version 3.5 (http://blogs.msdn.com/b/shawnfa/archive/2009/03/17/authenticated-symmetric-encryption-in-net.aspx). I'd like to use CBC-MAC or to create a MAC using a hash algorithm and append it to the message, but the login message contains very little information (basically just the username), and I was thinking this might create a weakness. Perhaps I'm wrong.
Lars A. Brekken
@Lars A. Brekken I'm sure there is another implementation in ASP or C# (or whatever your using). It wouldn't be that difficult to build your own and then verify it against .net 3.5's implementation.
Rook
@Lars A. Brekken if you do go with a hashed mac then you still need to use a secret. This could be transmitted over SSL, similar to a session id.
Rook
+1  A: 

Your idea is subject to a replay attack - if someone observes a user logging in, they can store the static-text-encrypted-with-symmetric-key and use it later to authenticate themselves.

The accepted way of doing this is a challenge/response. The client connects, the server generates a random challenge and sends it to the client, and the client responds with the encrypted version of the challenge (although you should actually use a HMAC here, rather than a block cipher, because otherwise your client is effectively a one-block decryption oracle!). It would also be safer to use two different random keys (provided at the same time over the web service), one for encryption and one for authentication.

Note though that this scheme, as written, is still susceptible to a man-in-the-middle attack. You are definitely better off using SSL, as The Rook suggests. This will require your client to generate a public key and send it to the web service. The web service responds with a signed certificate containing the client's public key along with the client's unique identifier (username, or whatever) in the DN field. The server on the separate connection verifies the client certificate used (ensuring it's signed by your web service), and verifies that the client identifier in the certificate matches the client that is asking to connect.

caf