【问题标题】:Can someone clarify how the PHP function crypt() works?有人可以澄清 PHP 函数 crypt() 的工作原理吗?
【发布时间】:2014-12-02 14:12:21
【问题描述】:

根据我的理解 crypt(string, salt),取盐,将其粘贴到字符串参数的加密版本的前面。

$pw = "secret";
$format_and_salt = $2y$10$MWRmZTkwMTc5ZGJjZDI1NT;
$hash = crypt($pw, $format_and_salt);

$hash 以$2y$10$MWRmZTkwMTc5ZGJjZDI1NOfGsQUgIu7ezETpe.uHjGqbmdrw2.vqm 的形式存储到数据库列hashed_password

或分解:

第一部分是 $format_and_salt:$2y$10$MWRmZTkwMTc5ZGJjZDI1N (sans the 'T')

+

第二部分是加密的$pw:OfGsQUgIu7ezETpe.uHjGqbmdrw2.vqm

如果我随后再次使用 crypt 来验证用户提交给 $_POST 的密码是否与数据库中存储的 hashed_pa​​ssword 相比,这两种情况的输出似乎都没有反映我上面描述的逻辑。所以我错过了一些东西。

那么:

$existing_hash = $admin['hashed_password']($admin 是一个最终派生自查询的数组)。

crypt($pw, $existing_hash) 返回$2y$10$MWRmZTkwMTc5ZGJjZDI1NOfGsQUgIu7ezETpe.uHjGqbmdrw2.vqm

与上面的$hash 相同。这可以验证或使用户提交到 $_POST 无效,但如前所述,如果我遵循上面第一个 crypt() 的逻辑,我希望:

第一部分是$existing_hash:$2y$10$MWRmZTkwMTc5ZGJjZDI1NOfGsQUgIu7ezETpe.uHjGqbmdrw2.vqm

+

第二部分是加密的$pw:OfGsQUgIu7ezETpe.uHjGqbmdrw2.vqm

我希望将其组合为: $2y$10$MWRmZTkwMTc5ZGJjZDI1NOfGsQUgIu7ezETpe.uHjGqbmdrw2.vqmOfGsQUgIu7ezETpe.uHjGqbmdrw2.vqm

有人能解释一下为什么原来的地穴和上面用来验证第一个地穴的地穴都有相同的输出吗?提前致谢。

【问题讨论】:

    标签: php password-encryption


    【解决方案1】:

    您正在使用 Blowfish 加密 - 仅使用 salt 的前 22 个字符。这是使用河豚的好处之一。

    来自PHP manual

    使用盐的 Blowfish 散列如下:“$2a$”、“$2x$”或“$2y$”、两位数的成本参数、“$”和字母表中的 22 个字符“./0- 9A-Za-z”。

    这意味着来自 $existing_hash 的盐最终是 $2y$10$MWRmZTkwMTc5ZGJjZDI1N - 与之前完全相同。

    【讨论】:

    • 其实是 BCrypt 散列(Blowfish 加密是另外一回事),否则就是正确答案。 crypt 函数仅从现有哈希中提取盐,并使用它来生成与输入的密码相当的哈希。
    • MWRmZTkwMTc5ZGJjZDI1N 只有 21 个字符。 $2y$10$ 算不算第 22 个字符?
    • @martinstoeckli 在 PHP 实现中被称为河豚。也许我应该说“你正在使用河豚选项”。
    • @mwotton - 嗯,Blowfish 是一种加密算法(双向),而 BCrypt 是从 Blowfish 派生的,但它是一种哈希算法(单向)。确实有点混乱。
    • @dbconfession - BCrypt 需要 22 个字符的盐,但它只使用 128 位中的 126 个。因此你的盐MWRmZTkwMTc5ZGJjZDI1NT 可以变成MWRmZTkwMTc5ZGJjZDI1NO。有关详细信息,请参阅此answer
    猜你喜欢
    • 2011-03-07
    • 2021-08-23
    • 2014-05-21
    • 1970-01-01
    • 2012-02-14
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多