It's disappointing that major web sites still aren't protecting their customer accounts properly. One of the more recent reports is about the controversial Gawker.com media empire where its complete customer login database has been placed on the Internet and hundreds of thousands of its user passwords already cracked using John the Ripper. Another major hack had unfortunate consequences for a security firm.
Unlike the earlier RockYou hack, where all the customer passwords were stored in plain text, Gawker used a relatively primitive password hashing scheme. Unfortunately, their scheme wasn't even close to adequate because of a combination of the primitive hashing, weak user passwords, and the enormous amount of firepower that modern hardware and software gives to attackers.
In today's world, where cryptographically-strong pseudo-random number generators and iterative hashing schemes such as PBKDF2 or scrypt combine to give an equal amount of firepower to defenders, this state of affairs is inexcusable. I thought it would be useful to package some C# code into a utilities library covering the following areas:
- Specifying password policies that can match most application requirements.
- Generating cryptographically-secure random passwords that satisfy a specified password policy.
- Measuring the strength (or more precisely, entropy) of human-generated and machine-generated passwords.
- Using random salts and key stretching to make password hashes more secure than the original passwords.
- Measuring the additional strength added by iterative salted hashes.
- Timing the password generation and password hashing processes.
Before diving into the detailed code, let's look at the major threat. Imagine that your website's security has been breached and its password database is now in the hands of the attacker. He can launch an offline attack on the database, and dump your users' account names and cracked passwords publicly on the Internet. When this happens, at the very least you have problems 1 and 2 in the list below, whilst your users have problems 3 and 4:
- Your organisation will have some rather unpleasant publicity.
- Many of your users will likely lose trust in your organisation.
- The dump will be harvested by people looking to compromise your application's user accounts.
- The dump will be harvested by people looking for passwords that might have been reused on other web sites.
So you're now in a race against time.
If your application stores the passwords in plain text like RockYou, it's "game over". Your best bet is first to warn your users about what happened and the implications. Then force them to change all of their user passwords, or change their passwords yourself.
If your application hashes the passwords using the same scheme as Gawker (DES crypt(3)), the situation may be a little better. It depends on the strength of your users' passwords and passphrases. Because DES can be executed extremely fast with modern hardware, weak passwords will be broken within a few minutes to a few hours. For these users, problems 3 and 4 in the bulleted list above will rapidly apply.
But for those users who used a much longer password, or hopefully a passphrase, the situation isn't quite as bad. DES crypt(3) compresses the password hash to fit the size of a DES key, so many passphrases will hash to the same value. Your users will still have problem 3 in the bulleted list above. But as the passphrase itself can't be disclosed by a successful match, your users won't have to worry about problem 4.
What's clear is that the stronger your password hashing scheme and your user passwords are, the more time you and your users have to deal with problems 3 and 4 above. The next installment in this series will look at password policies and how they can be implemented in software to increase the strength of user passwords.