How to hash and salt passwords

2019-02-05 03:59发布

I realize that this topic have been brought up sometimes, but I find myself not entirely sure on the topic just yet.

What I am wondering about how do you salt a hash and work with the salted hash? If the password is encrypted with a random generated salt, how can the we verify it when the user tries to authenticate? Do we need to store the generated hash in our database as well?

Is there any specific way the salt preferably should be generated? Which encryption method is favored to be used? From what I hear sha256 is quite alright.

Would it be an idea to have the hash "re-salted" when the user authenticates? And lastly is it any major security boost to rehash it a bunch of times?

Thank you!

5条回答
看我几分像从前
2楼-- · 2019-02-05 04:24

Three simple rules. Okay, five:

  1. Most important thing, if you want to consider your password storage being safe: allow strong passwords only e.g. at least 8 chars with some different case letters and numbers and even punctuation marks
  2. Allow users to use strong passwords only. Make a routine to check length and character range and refuse weak passwords. Even get yourself John the ripper database and check against it.
  3. Torture users wickedly, beat them up, until they choose good long and random enough passwords. Passwords! Not salt, of which everyone is delighted to talk for hours, but password itself should be random enough!
  4. Salt your passwords and store that salt along with user info. you can use user email and username as a perfect salt, no need to invent something extraordinary random.
  5. Certain algorithm is not that important, you can use MD5 as well. In real world there are very few people who would bother themselves with cracking user database of your famous Fishing And Grocery Fans Society site forums.
查看更多
叛逆
3楼-- · 2019-02-05 04:29

The answer is to not do it yourself. The one-liner that will do everything you need in PHP is to use bcrypt.

Read this, it's easy to understand and explains everything you asked: http://codahale.com/how-to-safely-store-a-password/

bcrypt takes into account the hashing by itself, and can be configured to be as "complex" as necessary to maintain the integrity of your users' passwords in the event of being hacked.

Oh, and we don't "encrypt" passwords, we hash them.

查看更多
叼着烟拽天下
4楼-- · 2019-02-05 04:35

You need to store both the hash and the salt that has been used to calculate the hash.

If you then want to check if an input is equivalent to the original input value, you can re-calculate the hash with the same salt and compare the stored hash with the new calculated one. If they are equal both input values are identical (up to some particular probability).

The choice of hashing algorithm is also important. Because there are fast hashing algorithms and rather slow hashing algorithms. And as you want to make is hard to find a collision (at least in brute-force), use a slower hashing algorithm.

查看更多
相关推荐>>
5楼-- · 2019-02-05 04:38

What I am wondering about how do you salt a hash and work with the salted hash? If the password is encrypted with a random generated salt, how can the we verify it when the user tries to authenticate? Do we need to store the generated hash in our database as well?

Yes. First you generate a salt, then generate a hash from the password plus the salt and save both hash and salt together.

Is there any specific way the salt preferably should be generated?

I doubt that there's consensus on what's preferable. I use /dev/random. e.g.

$salt = '$2a$12$' 
    . strtr(substr(base64_encode(shell_exec(
        'dd if=/dev/random bs=16 count=1 2>/dev/null'
        )), 0, 22), '+', '.')
    . '$';
$hash = crypt($input, $salt);

Which encryption method is favored to be used? From what I hear sha256 is quite alright.

See Computer Guru's answer, i.e. use bcrypt as in the example above. See the PHP manual page on crypt(). If bcrypt isn't on your system, one way to get it is the Suhosin patch.

Would it be an idea to have the hash "re-salted" when the user authenticates?

The salt just makes dictionary attacks slower. If you have a decent random salt to start with I wouldn't think changing it frequently would help. You'd probably be better off investing your effort in making users choose good passwords, changing them often enough and keeping your Blowfish cost parameter at a sensible value.

And lastly is it any major security boost to rehash it a bunch of times?

That question belongs in the world of cryptographic design. I recommend you leave that to the experts. In other words: forget it—just use best common practices.

查看更多
Fickle 薄情
6楼-- · 2019-02-05 04:41

What generally you do is something like:

salted = HASH(password . key); // DON'T DO IT LIKE THIS 

Where key is "the salt" - the secret key stored in configuration files. So in order to crack the password you would need both the secret key and the DB so it is good to store them in separate places.

Because the schema I had shown is not strong enough, it is better to use HMAC for this purpose rather then hand written salting. Such an operation is as simple as hash and PHP supports this.

salted = hash_hmac('sha1',password,key); // <-- this is ok

See this: http://php.net/manual/en/function.sha1.php

查看更多
登录 后发表回答