关于 PHP 的 password_hash() 的问题

Questions regarding PHP's password_hash()

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

我注意到如果

echo password_hash("12345", PASSWORD_DEFAULT);

然后我得到类似

的东西
y$PgMmle9Ue4o3m7ITJcGa0ucmWXSZgqbJBF9I4qd/aqzn/vQIwbi/O

所以我的问题是

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

2) 我可以只在 y$ 之后存储字符串并在需要使用密码时连接它吗?

3) 为什么要用y$?这在未来会改变吗?所以在我的数据库中,我的密码是 y$,有些密码是 y$?使用 password_verify?

一切都会 运行 顺利进行

从阅读password_hash的手册来看,在$aa$bb$中,bb似乎代表所用算法的"cost"和aa似乎(至少目前)总是 2y.

Wouldn't the part of y$ give a hint of what algorythm was used and make it easier for an attacker to know what the original string was?

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

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

Why y$ is used?

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

Could that change in the future?

我也这么认为。
第二部分已经有所不同,第一部分在 the manual 中提到为 the "y$" identifier,但不保证不会添加其他标识符。

So in my DB I have passwords with y$ and some with y$? and everything would run smoothly using password_verify?

看看 examples in the manual - 已经是这样了。
password_hash(..., PASSWORD_DEFAULT) 似乎产生 y$ 的前缀,但 password_hash(..., PASSWORD_BCRYPT, ['cost' => 12]) 产生 y$.

Can I just store the string after y$ and concatenate it anytime I have to work with the password?

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

$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

这样一来,如果攻击者没有您的源代码,他们就无法知道加密数据的含义,如果他们确实可以访问您的源代码,他们可以只看一下加密的内容无论如何都在使用。

但是,即使攻击者知道 password_hashPASSWORD_DEFAULT 被使用,他们也不应该能够破解它。