在 PHP 中发布迁移哈希算法

Issue Migrating Hashing Algorithm in PHP

我正在考虑迁移用于数据库中所有密码的哈希算法并寻找概念证明。

我正在阅读一个非常用户友好的概念,它不会强迫任何人更改他们的密码 here,它基本上允许通过 [一次迁移数据库中的所有密码] =32=]散列散列:

The idea is basically to hash the hash. Rather than waiting for users provide their existing password (p) upon next login, you immediately use the new hashing algorithm (H2) on the existing hash already produced by the old algorithm (H1):

hash = H2(hash) # where hash was previously equal to H1(p)

After doing that conversion, you are still perfectly able to perform password verification; you just need to compute H2(H1(p')) instead of the previous H1(p') whenever user tries to log in with password p'.

所以基本上我会:

  1. 使用新算法,使用旧哈希算法重新哈希当前存储在数据库中的所有密码。
  2. 当用户尝试验证时,用新算法包装旧算法以验证密码。

假设我要从 SHA1 迁移到 BCRYPT,我 运行 使用密码 11111111 进行以下测试:

// 1. Old hash algorithm used to store the password in the database and authenticate the login
hash('SHA1', '11111111') 
// result: a642a77abd7d4f51bf9226ceaf891fcbb5b299b8

// 2. This would be run to update the hashed values in the database to the new algorithm
password_hash('a642a77abd7d4f51bf9226ceaf891fcbb5b299b8', PASSWORD_BCRYPT)
//result: y$zetRoEVYvjug73Ee8k/cSOSLxFBLs0fNYGJDrdqFkyqGoe41baJ46

// 3. This would be run to authenticate a user after the database passwords have been updated to the new algorithm
password_hash(hash('SHA1', '11111111'), PASSWORD_BCRYPT)
// result: y$xANTOzHQaKxfKKqzTn9lVeJIgHH3YQok/eOegIeRmrHHUTJkx7pDS

理论上上面 2. 和 3. 的结果应该是一样的,并且需要这样才能起作用 - 但它们不是。

有什么我遗漏的吗?

这是因为每次password_hash生成的hash与之前生成的同一文本的hash不同

Theoretically the result of 2. and 3. above should be the same, and would need to be for this to work - but they are not.

不,他们不应该,也不必。 BCrypt 生成自己的 cryptographic salt,它是唯一且随机的,为相同的输入生成唯一的随机散列。

您不需要(或不想!)每次都生成相同的哈希值。您仍然可以将候选密码(通过 SHA* 传递)与存储的 bcrypt 哈希进行比较。

您不会 运行 password_hash(hash('SHA1', '11111111'), PASSWORD_BCRYPT) 根据存储的 bcrypt 哈希测试候选密码。您使用 password_verify 来处理输入和执行比较。