3

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?

4

3 回答 3

4

您将盐与散列密码一起存储在您的数据库中,即hash(salt+password).

如果您的数据库遭到破坏并且有人获得了所有的哈希值和盐,他们就无法对您的哈希值进行彩虹表攻击 - 他们将需要暴力破解每个哈希值。使用好的散列算法,蛮力攻击是不可行的。

什么是彩虹表攻击?

让我们假设一个通用的散列算法,hash(f)

作为攻击者,我预先计算了常用密码 ( f) 及其哈希值 ( hash(f))。现在,当我得到你的未加盐的哈希数据库时,我只需要在你的数据库中查找与我预先计算的表(彩虹表)匹配的哈希。

例如,如果我的彩虹表存储了f = qwerty, hash(f) = someRandomHash,我会在你的数据库中someRandomHash查找,一旦找到它,我就知道用户的密码是qwerty

但是,如果您对密码进行了加盐处理,当用户将他的密码设置为qwerty时,您计算他的哈希为hash('saltqwerty),这意味着您没有计算他的哈希,someRandomHash而是计算为someRandomSaltedHash。这使我的彩虹表完全无用。

我别无选择,只能暴力破解你的桌子。我知道盐,但我不知道密码,所以我必须计算密码hash(salt+password)的每一个可能的排列和组合。使用足够慢的散列算法,这可能需要几个世纪(最坏的情况)。

您如何登录用户?

用户提交他的 user_id 和密码。您在数据库中查询该用户的盐。然后计算hash(salt+password)并与存储在数据库中的哈希值进行比较。

于 2014-01-23T20:27:33.657 回答
3

可以安全地将散列密码和盐存储在同一个数据库中 - 想法是,由于盐每次都不同,即使完全相同的密码也会以不同的方式存储在数据库中,这实际上消除了与诸如md5-encoded 密码之类的东西。

出于明显的混乱,如果您能够使用或更高版本,则使用andPHP v5.5.0密码存储变得非常容易。password_hashpassword_verify

作为一个额外的好处,这些函数不需要您在数据库中有单独的passwordsalt字段 - 您可以简单地存储返回的password_hash值并使用password_verify明文密码进行验证。

于 2014-01-23T20:29:15.040 回答
0

我对高级安全数据库了解不多,但是这个怎么样?:

hashedPassword = hash(UsurID+GivenPassword)

因此,在登录时,您首先获得用户登录名和他的 ID,然后将给定的密码与数据库中已经存在的 hashedPassword 进行比较。正如我所说,我不知道这是否会提高安全性,但至少它使所有密码都不同,不是吗?

反正我也在学习中。

于 2014-01-23T20:36:46.853 回答