Question

I have read tons of questions and tutorials about encrypting a password, and while I've learned a lot, nowhere did I find an answer to this.

I want to use crypt() for hashing a password that I will store on Database. I also know I need to use a salt so it works properly, and I've read that the best way to generate a random salt is by using this or something similar.

If I understood correctly the process is this:

  1. User enters a password
  2. Random create a salt
  3. Hash password and salt
  4. Store result in database

But then how do I recover the salt when user tries to login?

  1. User enters his password
  2. I somehow add his own unique randomly generated salt
  3. Hash both of them together
  4. Compare it to hashed salted password stored in Database.

In a few questions I've found, one of the answers was to store the randomly generated salt on the database. But I thought the whole purpose of salting was to be more secure, if an attacker got access to my DB he would see the 'salt' fields and even if my passwords are encrypted he would gain easy access to accounts.

Other answers said that the 'salt' is prepended to the password when using crypt() so there is no need to store it in a separate field. My question is, how do I get access to it? Is there some function that does this and I'm totally missing?

Was it helpful?

Solution

You store the salt in your db, along with the hashed password, i.e. hash(salt+password).

If your database gets compromised and someone gets all the hashes and the salts, they cannot run a rainbow table attack against your hashes - they will need to brute force each hash. With a good hashing algorithm, the brute force attack is unfeasible.

What is a rainbow table attack?

Lets assume a generic hashing algorithm, hash(f).

I, as an attacker, precalculate common passwords (f) and their hashes (hash(f)). Now, when I get your unsalted database of hashes, I just need to look through your database for hashes that match my precalculated table (rainbow table).

For example, if my rainbow table stores that for f = qwerty, hash(f) = someRandomHash, I look through your database for someRandomHash and as soon as I find it, I know that user's password is qwerty.

However, if you salted your passwords, when a user set his password as qwerty, you calculated his hash as hash('saltqwerty), which means, you did not calculate his hash as someRandomHash but instead as someRandomSaltedHash. This renders my rainbow table completely useless.

I am left with no choice but to brute force your table. I know the salt, but I don't know the password, so I have to calculate hash(salt+password) for every possible permutation and combination of password. With a slow enough hashing algorithm, this can take centuries (worst case).

How do you login a user?

User submit his user_id and password. You query the database for the salt for that user. Then you compute hash(salt+password) and compare against the hash stored in your database.

OTHER TIPS

You can safely store a hashed password and a salt in the same database - the idea is that since the salt is different every time, even the exact same passwords will be stored differently in the database, which virtually eliminates brute-force lookup weaknesses associated with things like md5-encoded passwords.

Out of an obvious mass confusion, if you're able to use PHP v5.5.0 or higher, password storage has become remarkably easier with the use of password_hash and password_verify.

As an additional benefit, these functions don't require you to have separate password and salt fields in your database - you can simply store the returned password_hash value and use password_verify with the clear-text password to validate.

I don't know a lot about high level security DB, but how about this?:

hashedPassword = hash(UsurID+GivenPassword)

So, at logon time, youget first the User Login, and his ID, and then the given password to compare with the hashedPassword tha is already in DB. As I said, I dont know if this will increase security, but at least it makes all passwords differents, doesn't?

Anyway, I'm still learning too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top