Start by assuming a very bad situation – a copy of your database has been obtained by the bad guys, to attack off-line at their leisure. How safe are we? For those accounts with strong passwords, SHA is great and our user’s password data is well protected. Weak passwords are another story.

A cracker with the user table can pick off the low hanging fruit almost instantly. Before the cracking even begins, they pre-create a dictionary lookup table with two fields of “PWD” and “PWD_SHA”. By filling the table with the most common passwords and pre-generating the SHA for these records, the crack tool is ready to go. The cracker then simply join the this dictionary lookup table to the stolen user table, such as:

SELECT u.user_id, d.pwd
FROM user_table u, dictionary_lookup_table d
WHERE u.pwd_sha = d.pwd_sha;

Almost instantly all the user names with weak passwords will be presented. This is obviously very bad.

There are two steps to fixing this. The first is to prevent users from entering weak passwords, and the second is to make the cracking hard. Assuming a failure somewhere (e.g., weak passwords can be entered by the support help desk,  a new method of cracking weak passwords is found, etc.) both steps are vital for proper protection. For now I’m focused only on the latter, making cracking hard.

Adding salt helps enormously. It prevents the pre-calculation of SHA hashes for the most common passwords, although the low hanging fruit is still within reach. For each user record, the cracker must now append each dictionary word to the user’s salt, and then run the SHA algorithm. But now the cracker can’t zero in on the weak accounts, they need to probe all user passwords. However, assuming 1000 SHA calculations per second and a lookup dictionary of 60,000 common passwords, that comes to 1 user analyzed per minute. This is a great improvement over instant access, but it still leaves weak password cracking as possible.

One problem is that the salt is stored in the database, and by definition must be either clear text or decryptable into clear text. It would be nice if there was a layer of salt that was not clear text. Adding pepper (non-clear-text salt) is one possible answer, which makes even weak passwords well protected. The problem is how to maintain a non-clear-text string that can be used in the clear?

There are high end hardware solutions, the most well known being the  AACS encryption key that famously went viral in 2007. In this case the key is buried within the chips so it is very difficult to extract, and the strength of the key and the algorithms used makes it very difficult to crack. Other high end solutions keep the keys and algorithms only at the silicon layer. This might be a solution for some particular applications, but there are drawbacks, such as the database now being hardware dependent. If the key chips are unique then the database itself is put at risk. If the key chips are not unique then all the world’s databases are put at risk if the chips are potentially compromised, making the chip  cracking a difficult but high priority task for the crackers. In any case, these high end solutions-and-new-problems aren’t practical for the average database admin.

So, how do we store a non-clear-text string? It can’t be in the database, even in an encrypted form, because it must be decryptable. Therefore it needs to come from the web application configuration, probably stored along side the database login credentials.

This solves the weak passwords for the case outlined above, where a copy of the database is in the wild.  But this very bad situation isn’t a worst case situation. A hacker could be sitting in the database, watching all the traffic go by. They could have access to the traffic going between the web server and database server. They could have root access to the web server, and could be slurping everything in plain text.

For these apocalyptic situations there are other safeguards and remedies to consider. But walking down this progression of severity there are a few other options to consider.

The pepper needs to be applied to the password before it is passed to the database, and SHA applied at the web server. Otherwise a man-in-the-middle between the web server and the database server or someone in the live database can see the pepper.

The pepper needs to be strong, say 128 bits. If someone is in the database, they can create a new account with a known weak password, see the generated salt, and see the resulting salted and peppered SHA. If the pepper is weak, say 16 bits, then it would take only take 65535 SHA calls to discover the pepper value, at which point the protection from the pepper goes away.

In the aftermath of a break-in it is standard practice to change all the passwords, including the database password used by the web application. But what about the pepper? Since there are SHA values in use that rely upon the pepper, changing the pepper would destroy all those accounts’ passwords. The solution is to maintain an historical vector of peppers while maintaining a current/active one pepper. The user record would need to record the index of the pepper used by the stored password, in addition to the SHA password and the salt. When a user logs in, the appropriate pepper is used. Upon success, if the pepper used was old, then the latest-and-greatest pepper is used to create an updated SHA password. In the rare business case where users must log in at some base frequency and where retired users are purged, this can be a powerful construct. If the user is also required to change password periodically, a cracker with last month’s pepper won’t be able to get anywhere.

All this just to make weak passwords better protected. Whew. Is it worth it?

At the end of the day all we’ve really done is protect a password, where all the other information in the database is still compromised. If you get to this point your company may be sunk. But remember, you’re protecting more than your company assets, you are also charged with protecting your users. Those who use weak passwords are likely to be using those same weak passwords elsewhere in the world, probably with the same user name. For this reason alone – protecting your users’ identity and information in the greater world, outside of your company breach – it is worth the effort.