How Mac OS X Implements Password Authentication
Last night, I gave a presentation at PSIG 92 on Mac OS X password authentication. PSIG is a monthly Mac programmer get-together in northwest Illinois that's hosted by The NorthWest of Us and lead by Jonathan 'Wolf' Rentzsch. I've been attending for about the last year now, and I always look forward to it. The topics and conversations are interesting, and somehow we always manage to geek out into the wee hours of the morning. I highly recommend it, if you're around northwest Chicagoland and want to hang with some other really smart Mac developers.
Like I said, I gave last night's presentation and the topic was how Mac OS X implements password authentication. I think the slides on their own leave out a lot of detail, but I'm making them available in PDF, anyway. There's still enough good information in there to be entertaining. The talk covered various topics: the history of passwords on Unix and OS X, the basics of how cryptography is used to store passwords, the strengths and weaknesses of various password implementations, password attacking tools, and finally what constitutes a "good" password.
One of the topics that generated a lot of discussion, and I think I probably could have discussed better, is salts. Very briefly, salts are used to make attacking multiple passwords more difficult, and makes generating rainbow tables practically impossible. It does nothing to protect a single password. However, it protects multiple passwords (say a whole password file) by making dictionary attacks and brute force attacks much slower. Salts are a random bit of information essentially added to the password that makes the same plaintext password have a different hashed value. Using the
openssl command, you can generate passwords in multiple algorithms and formats. Here are two possible values for the password "foobar" in the Unix DES crypt(3) format:
% openssl passwd -crypt foobar jFUO4DTdeEmpw % openssl passwd -crypt foobar cye1Y9RMJIk/2
The salt is stored in plaintext, and is stored as the first two characters, i.e. "jF" for the first password and "cy" for the second. To verify a password, the operating system takes the salt and the plaintext password, creates a hash, and then compares the hashed values for a match. Again, we can demonstrate this with the
openssl command by telling it to use a specific salt, rather than generate a new one:
% openssl passwd -crypt -salt cy foobar cye1Y9RMJIk/2
We can do the same thing for FreeBSD's MD5-based passwords. Here are two examples of "foobar":
% openssl passwd -1 foobar $1$ZBvk.4b5$xL63iF/S/IMTnQgz9.80i/ % openssl passwd -1 foobar $1$QdAorUxg$UNly3tkv6xvo69je8gpPE0
The two middle dollar signs are used to delimit the salt. Thus in the passwords above, the salts are "ZBvk.4b5" and "QdAorUxg" respectively. You'll notice that the salts are larger than in Unix DES, which improves the effectiveness of the salt. The "$1" at the beginning is a version number that allows FreeBSD to use a different algorithm in the future. Again, we can use
openssl to show how the password would be verified by the OS:
% openssl passwd -1 -salt QdAorUxg foobar $1$QdAorUxg$UNly3tkv6xvo69je8gpPE0
Hopefully this makes the topic of salts a little more clear. If your still confused, try playing around with the
openssl passwd command on your own for a bit.
Since some of specific details of how Mac OS X implements passwords are not in the slides themselves (I talked about them in a demo I gave after the presentation), I would like to write up more about them in a future article.
Update: I've added Part 2 which covers password implementations on OS X versions 10.2, 10.3, and 10.4.