How are passwords stored in a database

Store passwords securely

Status: 2013-02-09

content

Storage as hash

Word has got around to a large extent that storing passwords in plain text is not a good idea. This is why it is often not the passwords that are saved, only their hash values. Hash methods such as MD5 or SHA1 calculate a cryptic checksum from plain text, from which the input value cannot be reconstructed. The following Python code calculates the SHA1 hash from the word "secret".

Instead of the password in plain text, only this hash value is saved in the database. In order to check the password when logging in, the hash value of it is calculated again and compared with the stored one. If an attacker gains access to the database with the user data, he can initially do little with the password hash values.

Salt hash values

Simple password hashes are not really secure because many users choose simple passwords. For them, however, there are tables with precalculated hash values ​​with which dictionary attacks can be carried out. In the dictionary, the plain text password is simply looked up for a hash value. Rainbow tables also offer a way to speed up the search for the plain text password. To prevent this type of attack, hash values ​​are "salted" with a few characters. To do this, a few random characters are appended to the password before the hash value is calculated. The additional characters ("salt value") are stored in plain text next to the hash value. When a user logs in, the "salt" is added to his password before the hash value is calculated, the hash value is calculated and compared with the salted hash in the database. The "salt" itself does not have to be protected from attackers, because it only serves to render the precalculated hash values ​​from rainbow tables worthless.

An example illustrates the procedure. A table with user data looks something like this:

| name | password_hash | salt | + ------ + ------------------------------------------ + ---------- + | Karl | 4676d5dbdfc7cd6eea15bfece83d1a58ef633a26 | u75Pe # mq |

When the user "Karl" logs in, both the password hash and the salt value are loaded from the database. This is attached "secret" to the transmitted password and the hash value is calculated:

This value is compared with the password hash from the database: if both match, the password is correct.

Ordinary hash algorithms are too fast

There is a fundamental problem with the hash algorithms used: they are too fast! These algorithms were designed to calculate cryptographic checksums of large amounts of data as quickly as possible. In order to slow down an attacker when calculating the hash values, the algorithm used should be slow. A common method is to calculate a hash value again from a hash value, for example a thousand times.

solution

It's easier and more elegant with BCrypt, which was invented especially to protect passwords. Shown here using the example of the Java variant jBCrypt:

BCrypt implementations are available for all common programming languages ​​(see section "See also" on the linked page). Another good alternative is PBKDF2.

Scrypt is even better, as it requires plenty of processor power as well as plenty of memory. This makes it difficult for attackers, even with special hardware, to crack a password hash. scrypt can be seen as the cutting edge of technology when it comes to password protection.

scrypt implementations:

Summary

Never save passwords in clear text! Append a few random characters (salt value) to passwords before the hash is calculated. If you're using a classic hash method, use it recursively. Use to store passwords securely preferably scrypt. BCrypt and PBKDF2 offer somewhat weaker protection, but also at a very high level.

More information

Major changes

  • 2012-11-15 Addition of scrypt
  • 2013-02-09 Correction of rainbow tables, dictionary attack