Why You Should Use Bcrypt to Hash Stored Passwords

Callum Hopkins
Callum Hopkins
Share

79% of participants in a recent ZoneAlarm survey were found to be using risky passwords. The data was used to present a very stylish infographic showing just how widespread the use of bad passwords really is. But no matter how hard it is to guess good passwords, they may be no more difficult to crack than bad ones depending on how the password is stored. Back in 2006, Reddit confirmed that a copy of their database had been stolen. More troubling was the fact that all of the user passwords had been stored in Reddit’s database without being masked in any way! Many users were panicked because they used the same password for Reddit on many other sites too. This was a huge security breach that resulted in a major problem for many unfortunate members of Reddit. It’s shocking to think some web developers still believe storing passwords as plain text with no encryption or hashing is a good way to store a password. It’s now 2011, and even though most developers agree that obfuscating stored passwords is a mandatory security feature for any user driven website, the practices used are falling behind. Some believe MD5 is a safe way to encode passwords; this is a lie (a very bad one, too)! MD5 is a good method to obscure non-sensitive data but it can be very easily “decoded” using rainbow tables. I once heard the story of a web developer who could not access a client’s database after the client deleted an email that had his password details. The developer, after scouring through the client’s files on their server, found a nicely formatted text file containing the MD5 password hash. It was just a quick copy and paste procedure into an online rainbow table lookup utility before they were logged into the client’s database. This story has a happy ending as the client’s password were recovered and development could continue, but the shocking truth is this process could have easily been carried out by the hands of a malicious hacker.

BCrypt

So what exactly is a good option for secure password hashing? One stand-out option in PHP is Bcrypt. Bcrypt is an adaptive hash function based on the Blowfish symmetric block cipher cryptographic algorithm. It uses a Key Factor (or Work Factor) which adjusts the cost of hashing, which is probably Bcrypt’s most notable feature. The ability to increase the cost (time and processing power) of hashing in the future as computers become more powerful is what really sets Bcrypt apart from other functions. Bcrypt can expand what is called its Key Factor to compensate for increasingly more-powerful computers and effectively “slow down” its hashing speed. Changing the Key Factor also influences the hash output, so this makes Bcrypt extremely resistant to rainbow table-based attacks. Newer computers can attempt to guess the original input of the hash, but it would still take the same amount of time (or longer) to verify whether its guess is a match or not. All this makes Bcrypt almost future proof! Bcrypt is incredibly slow to hash input compared to other functions, but this results in a much better output hash. When it comes to hashing and encryption, faster is never better. The longer it takes to encode something, the longer it takes a computer to try and identify the input. As Thomas Ptacek writes in his article Enough with the Rainbow Tables, “The better you can optimize your password hash function, the faster your password hash function gets, the weaker your scheme is.” In Bcrypt’s case, it’s very slow. Consider this quote from Coda Hale’s article How to Safely Store a Password:
How much slower is bcrypt than, say, MD5? Depends on the work factor. Using a work factor of 12, bcrypt hashes the password yaaa in about 0.3 seconds on my laptop. MD5, on the other hand, takes less than a microsecond.
Don’t think Bcrypt sounds like it would be too slow, though. As I mentioned earlier, you can set how large you want the cost of your your hashing to be. This means you can go for all-out-security but sacrifice time by using a huge Key Factor, or you can use a minimum Key Factor and reduce the time it takes to hash the input value. In either case, its this very feature that makes Bcrypt encryption so safe so you can’t lose with either option. It’s all up to you. To put the ability of Bcrypt into perspective, let’s compare it to a suitable hashing algorithm, such as SHA-2. SHA-2 doesn’t use any cryptographic algorithms, but instead uses a hashing algorithm to generate its output (though both SHA-2’s and Blowfish’s algorithms can stand up to a very similar level of scrutiny). Bcrypt is much slower than SHA-2, and thus theoretically better. SHA-2 also isn’t adaptive like Bcrypt and its Key Factor, so it will be more susceptible to table-based attacks as computer processing power increases. SHA-2 is a completely capable hashing function for now, but Bcrypt wins out because it’s speed (with hashing, slower is always better) and adaptability.

Using Bcrypt in PHP

You might be thinking, “jeez these all seem to be very complex functions… is it really worth taking the time to change my password hashing strategy to use Bcrypt?” The answer is YES! Bcrypt is easy to use and will be worth using in the long run. Bcrypt is available to you already if you are running PHP version 5.3, simply by using the crypt() function with a Blowfish required salt. It may be available in earlier versions if your system supports them, but I recommend 5.3 because PHP contains its own implementation of algorithm thus eliminating any additional dependencies). You can check if Bcrypt will work on your server by checking whether or not the CRYPT_BLOWFISH constant is defined and represents 1:
<?php
if (defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH) {
    echo "CRYPT_BLOWFISH is enabled!";
}
else {
    echo "CRYPT_BLOWFISH is not available";
}
After that, you only have to use code similar the following to hash you passwords before storing them:
<?php
$salt = '$2a$07$R.gJb2U2N.FmZ4hPp1y2CN$';
crypt("secretpassword", $salt);
The salt must start with $2a$
followed by a two-digit Key Factor and another dollar-sign, and then contain 22 alphanumeric characters (a period and slash are also allowed). The PHP Manual explains the restrictions on the salt:
[…] salt as follows: “$2a$”, a two digit cost parameter, “$”, and 22 digits from the alphabet “./0-9A-Za-z”. Using characters outside of this range in the salt will cause crypt() to return a zero-length string. The two digit cost parameter is the base-2 logarithm of the iteration count for the underlying Blowfish-based hashing algorithmeter and must be in range 04-31, values outside this range will cause crypt() to fail.

Summary

PHP allows developers to use Bcrypt with the greatest of ease, which begs the question why are you not using it? If you are running a version lower than 5.3, I implore you to upgrade your PHP installation. The importance of using a secure hashing function such as Bcrypt should be vital to anyone creating a web application that will store users’ passwords and other sensitive data. Besides its ease, I encourage you to use Bcrypt because of the fact it will keep up with Moore’s Law. I know I’ve already covered this earlier, but I feel the need to stress how important this fact is. If you start using Bcrypt now, you can rest assured all your users’ passwords are hashed with a function that is not going to be made obsolete over night. The key to this is the ability to customize the work rate, or Key Factor as I referred to it earlier. So there you have it, my personal recommendation why you should be using Bcrypt to hash passwords and other sensitive data. Here is a list of sites and articles you can read if you’d like to learn more about Bcrypt or Blowfish:
Image via Valerie Potapova / Shutterstock

Frequently Asked Questions about Bcrypt for Password Hashing

Why is Bcrypt considered a secure method for password hashing?

Bcrypt is considered a secure method for password hashing due to its adaptability and resistance to brute force attacks. It uses a cost factor that determines the amount of computing power required to hash passwords. This means as computers become more powerful, the cost factor can be increased to maintain a high level of security. Additionally, Bcrypt uses a salt (random data) for each password, making it resistant to rainbow table attacks.

How does Bcrypt compare to other password hashing algorithms like AES?

While AES is a symmetric encryption algorithm used for encrypting data, Bcrypt is a password hashing function. The main difference is that AES requires you to keep the encryption key safe, while Bcrypt doesn’t need to store any keys. Bcrypt is designed to be slow and computationally intensive, which makes it more resistant to brute force attacks compared to AES.

What are the potential drawbacks of using Bcrypt?

One potential drawback of using Bcrypt is its computational intensity, which can lead to slower response times, especially for systems with a large number of users. However, this is also what makes it secure. Another limitation is that Bcrypt can only handle passwords up to 72 characters.

How does the cost factor in Bcrypt enhance security?

The cost factor in Bcrypt determines the amount of time it takes to compute the hash. A higher cost factor means it takes longer to compute the hash, making it more difficult for an attacker to guess the password through brute force attacks. As computing power increases, the cost factor can be adjusted accordingly to maintain security.

Can Bcrypt be used for hashing other sensitive data apart from passwords?

Bcrypt is specifically designed for password hashing and is not suitable for hashing other types of data. For other sensitive data, encryption algorithms like AES or RSA are more appropriate.

How does Bcrypt handle salts and why are they important?

Bcrypt automatically generates and appends a salt to each password before hashing. Salts are important because they ensure that even if two users have the same password, their hashed passwords will be different. This prevents attackers from using precomputed tables (rainbow tables) to crack the password.

Is Bcrypt suitable for all types of applications?

Bcrypt is suitable for most applications that require secure password storage. However, due to its computational intensity, it may not be suitable for systems with a large number of users or systems that require fast response times.

How does Bcrypt protect against brute force attacks?

Bcrypt protects against brute force attacks by being computationally intensive. This means it takes a significant amount of time to compute the hash for a password. Therefore, an attacker attempting to guess the password by trying all possible combinations would need an impractical amount of time and resources.

What happens if the cost factor in Bcrypt is set too high?

If the cost factor is set too high, it can significantly slow down the system and lead to poor performance. It’s important to find a balance between security and performance when setting the cost factor.

Can Bcrypt be used in combination with other security measures?

Yes, Bcrypt can and should be used in combination with other security measures. While Bcrypt provides secure password storage, other aspects of security such as secure transmission of data, user authentication, and access control should also be considered.