关于PHP的password_hash()的问题

Mat*_*epa 2 php password-hash

我有几个关于PHPpassword_hash函数的问题。

我注意到如果这样做

echo password_hash("12345", PASSWORD_DEFAULT);
Run Code Online (Sandbox Code Playgroud)

然后我得到类似的东西

$2y$10$PgMmle9Ue4o3m7ITJcGa0ucmWXSZgqbJBF9I4qd/aqzn/vQIwbi/O
Run Code Online (Sandbox Code Playgroud)

所以我的问题是

1) 的部分是否会$2y$10$提示所使用的算法,并使攻击者更容易知道原始字符串是什么?

2)我可以将字符串存储在后面$2y$10$并在需要使用密码时将其连接起来吗?

3)为什么$2y$10$使用?未来这种情况会改变吗?那么在我的数据库中,我的密码是$2y$10$,有些是$2y$25$password_verify使用?一切都会顺利进行

Sig*_*uza 5

从阅读手册来看,password_hash它看起来像$aa$bb$bb似乎代表所使用算法的“成本”,并且aa似乎(至少目前)总是2y

的部分是否会$2y$10$提示所使用的算法,并使攻击者更容易知道原始字符串是什么?

是的,它会给出一个提示,但是

  1. 对于许多函数来说,字符串的整个其余部分也是如此(例如,md5/sha1 哈希值将始终由 32/40 个十六进制字符组成)。
  2. 这不应该是一个问题,因为无论如何你都不应该依赖于混淆,而应该依赖于强大的算法(正如 arkascha 在他的评论中正确指出的那样)。

为什么$2y$10$使用?

因为有人认为这是个好主意。

未来这种情况会改变吗?

我想是这样。
第二部分已经发生变化,第一部分在手册中提到为the "$2y$" identifier,但不保证不会添加其他标识符。

那么在我的数据库中,我的密码是$2y$10$,有些是$2y$25$?使用password_verify一切都会顺利进行?

看一下手册中的示例- 已经是这样了。
password_hash(..., PASSWORD_DEFAULT)似乎产生前缀$2y$10$,但password_hash(..., PASSWORD_BCRYPT, ['cost' => 12])产生$2y$12$.

我可以只存储字符串并$2y$10$在需要使用密码时将其连接起来吗?

我建议不要这样做。
您也许可以让它工作,甚至可以防止它因任意更改而中断,但如果您唯一关心的是加密字符串暗示所使用的加密方法,那么更好的选择是添加额外的对称加密层。
例如:

$password = password_hash("12345", PASSWORD_DEFAULT);
$key = pack('H*', md5('lorem').md5('ipsum')); // Must be 16, 24 or 32 bits
$secret = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $password, MCRYPT_MODE_ECB);
// Store $secret in the database
Run Code Online (Sandbox Code Playgroud)

这样,如果攻击者没有您的源代码,他们就无法知道加密数据的含义,而如果他们确实可以访问您的源代码,他们就可以查看所使用的加密方式。

但同样,即使攻击者知道这一点password_hash并且PASSWORD_DEFAULT正在被利用,他们也不应该能够破解它。