-1

I am facing the never ending problem How to store passwords in DB?. As far as I read recently there ware a few of the previously considered safe algorithms, which had been marked as insecure. So I am struggling to find a up-to-date resource which describes the ones that are not secure any more.

I was thinking of combining two or three algos, but I remember back in the day it was considered insecure, i.e exposes the hash to attacks. The combination I was thinking of was something like that:

data_h1 = sha256(sha1(data_salt).sha1([username|email]).sha1(data_peper))
data_h2 = sha256(sha1(data_salt).sha1(user_entered_password).sha1(data_pepper))

hmac(
sha512,
data,
sha512(general_salt.data_h1.data_h2.general_pepper)
);

Where data_salt and data_pepper are constants, hard-coded in to the application, but are different than general_salt and general_pepper which are as well hard-coded constants. [username|email] is the value supplied by the user on registration and when logging in, as well as *user_entered_password* (doh!).

  1. Will this compromise security in some way? (if no go to next)
  2. Will there be a major bottleneck due to the hash-o-mania which will be going on in the process of generation? (go to next)
  3. Any recommendations on the approach showed above?

My questions goes for PHP, but will be good to see what will you guys recommend and what will your comments be in general, b`cuz I do think that this is very common task, and many people still use only MD5 or SHA1 (or better yet, storing in plain text).

DaGhostman Dimitrov
  • 1,608
  • 20
  • 44
  • possible duplicate of [Secure hash and salt for PHP passwords](http://stackoverflow.com/questions/401656/secure-hash-and-salt-for-php-passwords) – PeeHaa Oct 06 '13 at 01:19
  • Pleeeease don't use those weird, totally outdated and within-seconds hackable self-built "solutions". Use the new PHP 5.5 password hashing functions instead. By the way I deleted my right-to-the-point answer because people were downvoting it (even if it's totally correct). – Sliq Oct 06 '13 at 01:42
  • The suggestion about 5.5 is not adequate, because it is not widely supported (I barely can think of a provider offering it, excluding dedicated servers and clouds). Probably that was the reason for the DVs @Panique. As the approach is very bad(I can tell that, but was just trying to illustrate the idea[which many people didn't understand]) And quoting myself with: ` As far as I read recently there were a few of the previously considered safe algorithms, which had been marked as insecure. So I am struggling to find a up-to-date resource which describes the ones that are not secure any more.` – DaGhostman Dimitrov Oct 07 '13 at 10:31
  • 1
    @DaGhostmanDimitrov I hear that quite often, but the thing is, the PHP 5.5 password hashing functions are also available in 5.3 and 5.4 (there's an official compatibility pack). – Sliq Oct 07 '13 at 11:51

2 Answers2

4

The main reason not to use SHA-1 or SHA-256 alone for hashing passwords is that they are fast, relatively speaking. Password authentication is vulnerable to dictionary attacks and brute-force attacks, since users tend to include common words in their passwords and use relatively short passwords, making them easier to guess than encryption keys.

Hash functions like bcrypt and PBKDF2 are recommended because they are slow. They can be tuned to take almost any amount of time; it should take as long as possible to hash a password without causing unreasonable delay. This will help slow dictionary attacks and brute force attacks.

However, this is not the only security consideration for password storage.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
1

When "storing" passwords you do not actually store the password, you store its one-way hash. The reason for this is to prevent even someone with access to the system from learning a user's password. The "one way" aspect of the hash means that, while it is possible to create a hash from the plaintext, it is impossible to learn the plaintext from the hash.

In addition, all passwords should be concatenated with salt (a random sequence of digits) before being hashed. The salt value should be stored along with the hash in the database. The salt must be ROW-SPECIFIC, i.e. every password should have its own salt.

Why must hashes be row-specific? Imagine a hacker has somehow obtained a copy of your database. Normally he's up against a pretty big brute force task. If you have only one hash, the hacker can examine all the rows and find rows that occur the most frequently, because the same password + the same salt always renders the same hash. So with this information he can guess that those rows contain commonly-used passwords. He can then use that information to reduce the size of his brute force problem. Or he can try to learn one of those users' passwords and then be able to use that password on any of the other users' accounts that have the same hash. The whole point of the salt is to prevent attacks of that nature.

Use a decent one-way cryptographically secure hash with a user-specific salt. That is the standard means of storing passwords.

The addition of application-specific "pepper" (which is the same every row, and must be cryptographically random and held in a secure location) tranforms the hash into an HMAC (Hash-Based Message Authentication Code), which is even better. If someone knows your hashing algorithm and salt but doesn't know the pepper, he will have a much harder time guessing the password.

John Wu
  • 50,556
  • 8
  • 44
  • 80