简体   繁体   English

PHP password_hash()/ bcrypt

[英]PHP password_hash() / bcrypt

I am checking out the bcrypt hash-algorithm. 我正在检查bcrypt哈希算法。

My first test with password_hash(): 我用password_hash()进行的第一次测试:

echo password_hash("123", PASSWORD_BCRYPT, array( "salt" => "1234567890123456789012" ));
echo password_hash("123", PASSWORD_BCRYPT, array( "salt" => "1234567890123456789012xxxxxxxxxxxxxxx" ));

Both will return '$2y$10$123456789012345678901uiaLpJxTpf6VbfI5NADlsRsfvEm6aq9C'. 两者都将返回'$ 2y $ 10 $ 123456789012345678901uiaLpJxTpf6VbfI5NADlsRsfvEm6aq9C'。

  1. Why the heck is the salt stored inside of the hash? 盐为什么存储在哈希表中? This makes no sense at all for me. 这对我完全没有意义。 A attacker who gets the hashes from a database can´t do anything with them, if he does not know the salt. 如果攻击者不知道哈希值,那么从数据库中获取哈希值就无法对其进行任何处理。
  2. Why do I get the same Hash with two different salts? 为什么我用两种不同的盐得到相同的哈希值? Are only the first 22 chars used for the salt passed to the function? 仅将用于盐的前22个字符传递给函数吗?

Thank you very much! 非常感谢你!

The salt isn't a secret, it's generally stored in the database with the hash, and could just as well be stored directly in the hash, like password_hash does. 盐不是秘密,它通常与哈希一起存储在数据库中,也可以像password_hash一样直接存储在哈希中。

The salt creates uniqueness so the hash can't easily be cracked with things like rainbow tables or dictionaries, it doesn't really add security other than making the hash more unique so running a dictionary or table against the hash doesn't match because it also includes the salt. 盐创造了唯一性,因此哈希不能轻易地被彩虹表或字典之类的东西破解,除了使哈希变得更加独特之外,它并没有真正增加安全性,因此针对哈希运行字典或表不匹配,因为还包括盐。

If you omit the salt, a random salt will be generated by password_hash() for each password hashed. 如果省略盐, password_hash()将为每个散列的password_hash()生成随机盐。 This is the intended mode of operation, and you shouldn't supply your own salts. 这是预期的操作模式,不应提供自己的盐。
PHP7 will actually produce a warning telling you that using the salt option is deprecated. PHP7实际上会产生警告,告诉您不建议使用salt选项。

The salt passed needs to be at least 22 characters, but most underlying algorithms, like bcrypt, doesn't use the entire salt, see this answer for more on that 传递的salt必须至少为22个字符,但是大多数基础算法(例如bcrypt)不会使用整个salt,有关更多信息,请参见此答案

Salts are not something you have to strive to keep secret. 盐不是您必须努力保持机密的东西。 Their protection is effective even when known. 即使已知,它们的保护也是有效的。 https://crackstation.net/hashing-security.htm https://crackstation.net/hashing-security.htm

The salt does not need to be secret. 盐不必是秘密的。 Just by randomizing the hashes, lookup tables, reverse lookup tables, and rainbow tables become ineffective. 仅通过将散列随机化,查找表,反向查找表和Rainbow表就失效了。 An attacker won't know in advance what the salt will be, so they can't pre-compute a lookup table or rainbow table. 攻击者不会预先知道盐的含量,因此他们无法预先计算查找表或彩虹表。 If each user's password is hashed with a different salt, the reverse lookup table attack won't work either. 如果每个用户的密码都用不同的盐进行散列,则反向查找表攻击也将不起作用。

Since you appear to be using a fixed salt value, heed this: 由于您似乎使用的是固定的食盐值,因此请注意以下几点:

A common mistake is to use the same salt in each hash. 一个常见的错误是在每个哈希中使用相同的盐。 Either the salt is hard-coded into the program, or is generated randomly once. 盐要么被硬编码到程序中,要么随机生成一次。 This is ineffective because if two users have the same password, they'll still have the same hash. 这是无效的,因为如果两个用户使用相同的密码,他们将仍然具有相同的哈希值。 An attacker can still use a reverse lookup table attack to run a dictionary attack on every hash at the same time. 攻击者仍然可以使用反向查找表攻击对每个哈希同时运行字典攻击。 They just have to apply the salt to each password guess before they hash it. 他们只需要在对每个密码猜测进行哈希处理之前就应用盐。 If the salt is hard-coded into a popular product, lookup tables and rainbow tables can be built for that salt, to make it easier to crack hashes generated by the product. 如果将盐硬编码为流行产品,则可以为该盐建立查找表和彩虹表,以使其更容易破解该产品生成的哈希。

I'd suggest using password_hash without its optional parameters. 我建议使用不带可选参数的password_hash The default function is built to be highly secure and by specifying your own algorithm and options you potentially weaken its function. 默认功能的构建具有很高的安全性,通过指定自己的算法和选项,可能会削弱其功能。

Per the PHP documentation : 根据PHP文档

Caution It is strongly recommended that you do not generate your own salt for this function. 注意强烈建议您不要为此功能生成自己的盐。 It will create a secure salt automatically for you if you do not specify one. 如果您不指定盐,它将自动为您创建安全盐。

edit: Here's why keeping the salt secret in bcrypt is pointless. 编辑:这就是为什么将盐秘密保留在bcrypt中是毫无意义的原因。

Per this post , there are 3,025,989,069,143,040 possible combinations in an 8 character password. 根据这篇文章 ,在8个字符的密码中有3,025,989,069,143,040个可能的组合。 You should generally tune bcrypt's work factor to take 0.1 seconds to hash a password. 通常,您应该将bcrypt的工作因数调整为需要0.1秒来哈希密码。 This means calculating all possibilities takes 302,598,906,914,304 seconds. 这意味着计算所有可能性需要302,598,906,914,304秒。 That is 9,588 millennia . 那是9,588 千年

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM