How secure is PBKDF2

Tips for securely storing passwords

Have you already thought about whether you can save your users' passwords securely? What does safe mean in this context?

Suppose an attacker succeeds in stealing your database completely. In addition, assume that your users use the same password for other services, for example for their e-mail account. What does this mean for your users?

If you store passwords in the database as clear text, hackers will love you. You can't make it any easier for an attacker. Even if you can hardly believe it, you encounter this regularly.

Maybe you save the passwords encrypted in the database? While this shows that you are aware of the problem, unfortunately it is not certain either. A prominent example is the software manufacturer Adobe. In 2013, the company lost 152 million passwords including the associated e-mail addresses. The reputational damage was of course enormous.

The problem with encrypting passwords is the fact that encryptions can be reversed. If an attacker knows the key, all passwords can be decrypted.

To store passwords securely, you must use a cryptographic hash function. A cryptographic hash function is one-way encryption that generates a hash from the plaintext password. It is therefore not possible to calculate the password from the hash.

Unfortunately, that is not enough. On the one hand, older hash functions are no longer considered secure. On the other hand, there are also possibilities of attack against the secure hash functions.

The insecure hash functions include MD4, MD5, SHA and SHA-1. Do not use these hash functions for storing passwords.

Even if secure cryptographic hash functions cannot be reversed, they are not automatically secure. There are countless dictionary lists on the internet with hashes already calculated. Many standard passwords can be cracked with it. To make this more difficult, you should have the passwords first before hashing salt.

Under salt one understands the inclusion of a randomly generated value, the salt. This salt is included in the calculation of the hash, which gives a totally different result. It is also important to mention that a new salt is generated for each password.

There are several hash functions that are highly recommended. I will go into more detail on three.

PBKDF2

PBKDF2 stands for Password-Based Key Derivation Function 2 and was standardized in 2000 as RFC 2898. The .NET Framework implements this function in the class Rfc2898DeriveBytes.

First the salt is calculated, for this I use the class RNGCryptoServiceProvider. In addition to the salt and password, the Rfc2898DeriveBytes class also requires a number of laps. The larger this number is chosen, the longer it takes to calculate the hash. I choose here 150000, so the calculation takes about a second.

To save the hash in the database, the salt is added to the hash and returned as a Base64 string.

bcrypt

Bcrypt is based on the Blowfish algorithm and was released in 1999. There are several implementations for .NET, one of which is BCrypt.Net.

First you install the NuGet package.

The use of the library is then a one-liner. First the password is transferred, then a factor that increases the number of laps. I choose here 12, which means that the calculation also takes about a second.

scrypt

Scrypt was released in 2010 and is therefore even less researched and tested than PBKDF2 and bcrypt. However, the algorithm is considered to be similarly secure. There is also an implementation for the .NET Framework that is available in the CryptSharp library.

To do this, first install the NuGet package.

As with PBKDF2, a random salt is generated first. In addition to a password and salt, the algorithm also needs a number of rounds, here 32768which again takes about a second. As with PBKDF2, the salt is combined with the hash and returned as a Base64 string.

If you run all three functions, the result is the following:

More tips

  • Unfortunately, many users use bad passwords like 123456, password or qwerty. Use a blacklist for bad passwords.
  • Encourage your users to choose strong passwords themselves by specifying the password strength.
  • Don't put any restrictions. Neither in the length of the password nor in the special characters used.