Library tutorials & articles

You Want Salt With That?

Challenge-Response

My friend Kristen asked me over the weekend when I was going to stop blogging about crypto math and say something funny again. Everyone's a critic!

Patience. my dear. Today, the final entry in my series on salt. Tomorrow, who knows?

***********************

So far we've got a system whereby the server does not actually know what your password is, it just has a salted hash of your password. But we're still sending the password over the wire in clear text, which seems risky.

System #4

What if the hash goes over the wire?  The client sends the user name to the server. The server sends the password salt to the client.  The client appends the password to the password salt, hashes the result, and sends the hash to the server. The server compares the hash from the client to the hash in the user list. Now the password never goes over the wire at all.  Awesome!

Unfortunately, this system is worse. In previous systems the eavesdropper got the password; in this system the eavesdropper gets the salted hash.  The eavesdropper can then write their own client which sends that username and salted hash to the server.

And the "steal the password list" attack just came back; now an attacker who gets the password list gets all the salted hashes, and can use them to impersonate the user. Sure, the attacker will still find it hard to deduce the original password from the salted hash, but he doesn't need to deduce the password anymore. (Unless of course the attacker is attempting to deduce your password on one system so that he can use it to attack another system that you use. This is why it's a bad idea to use the same password for two different systems.)

Essentially we've turned the salted hash into a "password equivalent". Can we fix this up?

System #5

How about this?

The client sends the username to the server. The server creates a second random salt which is NOT stored in the user list.  This random salt is used only once -- we either make it so big that odds of generating it again are low, or keep a list of previously used random salts and pick a new one if we have a collision. We'll call the random salt "the challenge" for reasons which will become apparent in a minute.

The server sends the user's password salt and the challenge to the client. The client appends the password salt to the password and hashes the salted password.  It converts the salted hash to a string, appends the string to the challenge, and hashes the resulting string to form the "response" hash.  The response is sent across the wire.

The server then does the same thing – converts the stored salted password hash to a string, appends it to the challenge, and hashes the resulting string.  If the response from the client is equal to the value the server just computed, then the client must have computed the same salted hash, and therefore knows the password.

Now what does the eavesdropper know?  The eavesdropper knows the username, the password salt, the challenge and the response.  The eavesdropper has enough information to launch an offline dictionary attack against that user. But since the random challenge is never going to be used again, the fact that the attacker knows a valid challenge/response pair is essentially irrelevant.

This system has the downside that an attacker who gets the password file has obtained password equivalents, so no dictionary attack is necessary. (Unless of course the attacker is trying to determine a user's password in order to try it against the user's account on a different system!)

Fortunately, these weaknesses can be mitigated somewhat by changing your password frequently, not using the same passwords for different accounts, never using common dictionary words as passwords, and making passwords long -- passphrases are better than passwords.

***********

This general challenge-response pattern is quite common in authentication systems that rely upon shared secrets, because at no point is the original secret password ever actually stored or transmitted!   With such a system, a machine that does not know your secret can verify that you do know it -- almost seems magical, doesn't it? Of course, now that you know how it works, it's not quite so magical -- the salted hash is essentially the shared secret, and it is stored and transmitted.

Clearly we could go on, adding more and more layers of encryption to this system to further mitigate these vulnerabilities, but I'm going to stop here. Readers interested in ways to solve problems such as mutual authentication (where the server authenticates the client AND the client verifies that it is talking to the right server) or other heavy-duty authentication tasks should read this charming dialogue on the design of the Kerberos authentication system: http://web.mit.edu/kerberos/www/dialogue.html

The foregoing is of course just a sketch with lots of details glossed over and greatly simplified for didactic purposes. Real  professional-grade authentication systems do not work exactly like any of my sketches, though several are quite similar.

Unix boxes used to typically use a 12 bit salt and hash it with a 56 bit password using a DES-based hash, for instance. That's pretty weak! A 12 bit salt only makes construction of a dictionary take 4096 times longer -- one dictionary for each possible salt.  In modern systems the more secure MD5 hash is often used now, which supports arbitrarily large salts. Unix boxes also used to keep the user list in the clear, so that anyone could read the salted hashes of the passwords; nowadays the encrypted passwords are kept in a file that can only be read by the operating system itself -- defense in depth!

NT by contrast uses an unsalted 128 bit MD5 hash to store the password equivalent, so it is susceptible to dictionary attacks should the password file be stolen.  NTLMv2 is an authentication system based on some of the challenge-response ideas from System #5. It hashes the password, user name, domain, and current time in a fairly complex way; I'll spare you the details. And of course, many NT and unix boxes use Kerberos-based authentication these days.

Comments

  1. 13 Jun 2005 at 17:26

    Nice piece.  Having previously just used a simple salt to hash with password at client I would like to try using the method 5.


    This requires a hash on the server which in my case would be MS-SQL.  I could use an RC4 algorithm I've got knocking around for SQL but I'd rather use MD5 so a question.  How would I implement MD5 hashing of a variable value within T-SQL?


    Any help gratefully received.

  2. 30 May 2005 at 23:00
    well it's a good piece
  3. 01 Jan 1999 at 00:00

    This thread is for discussions of You Want Salt With That?.

Leave a comment

Sign in or Join us (it's free).

Eric Lippert

Related discussion

Related podcasts

  • Over Two Decades at Microsoft - Larry Osterman

    Scott chats with Larry Osterman, the man who makes Windows go "ding", about his two-plus decades working for Microsoft. They chat about sound, Vista, Security and generally geek out.

Events coming up

  • Feb 4

    Securing Web Applications Training Course

    London , United Kingdom

    The Securing Web Applications training course is a one day hands on event targeted at web developers. The courses is delivered by Sec-1 whos main activity is the assessment of web applications for corporate and government clients.

We'd love to hear what you think! Submit ideas or give us feedback