PHP crypt 和 salt - 请进一步说明

Posted

技术标签:

【中文标题】PHP crypt 和 salt - 请进一步说明【英文标题】:PHP crypt and salt - more clarification please 【发布时间】:2011-01-12 15:16:53 【问题描述】:

我昨天在这里,得到了一些非常好的答案。我把我得到的东西放在一起,我认为这是一个相当安全的算法。我在使用带有生成盐的 for 循环的河豚时遇到问题。

我正在使用 base64 字符和 for 循环来获取随机字符串。我想把这个生成的字符串作为盐插入到crypt函数中。

因为关于河豚的文档太少了,而且 php 文档甚至都没有提到它,所以我在这里有点摸不着头脑。

真正奇怪的是,如果你以现在的方式运行这段代码,它不会失败。从 for 循环 从 crypt 函数中删除 either '$2a$07$',它会间歇地 返回一个加密字符串。我对河豚的理解是,加密字符串 必须 以 '$2a$07$' 开头并以 "$' 结尾,因此 crypt 函数中的连接。我真的不需要上面的开始字符串for 循环,只是想摆脱它。

我还想澄清一下将随机盐存储在数据库中还是通过将 crypt 函数的输出存储在数据库中的最佳做法?

昨天,没有真正的代码被抛出,只是讨论。今天我想把一些代码放在一起,并有一些相当安全的东西。如果有人能想出更好的算法,我总是愿意的。

$base64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
$salt = '$2a$07$';

for($i=0; $i<60; $i++)

    $salt .= $base64[rand(0,63)];


return crypt('password', '$2a$07$'.$salt.'$');

【问题讨论】:

你在盐值前面加了两次$2a$07$,这是故意的吗? 是的。这就是我发帖的原因。如果您删除其中任何一个字符串,crypt 函数将随机返回一个加密字符串。我想从 for 循环上方删除字符串并将字符串保留在 crypt 函数中。当我删除它时,crypt 功能失败。 如果您按原样运行此代码,它不会失败。删除这些 $2a$07$ 字符串中的任何一个都会失败。 快速查看文档说河豚的盐必须是 16 个字符长;你试过减少盐的长度吗? 我还从 PHP 网站上的一位贡献用户那里找到了这个。 “Blowfish 不使用 16 个字符的盐,它使用 16 个 字节 的盐。” 【参考方案1】:

似乎crypt() 不喜欢盐中的+ 字符,以及许多其他特殊字符(*% 等)。如果您将它们过滤掉,它应该在每次尝试时都有效(并且无需重复盐 id 字符串)。

【讨论】:

我不知道为什么如果你附加盐 id 两次它会起作用,但也许第二个 id 中的一个 $ 使它在此之后停止解析盐或类似的东西。 >_ 哇,你是对的。它没有失败过一次。我刚刚删除了 base64 字符串中的最后两个字符。 盐的有效字符是[a-zA-Z0-9./] - 真的,这应该在PHP文档中说明。【参考方案2】:

我知道这个问题现在几乎是古老的历史,但是为了任何通过谷歌搜索找到它的人的利益,在这个问题的答案中有一个非常详细的关于 bcrypt/EksBlowfish 盐如何工作的描述:

Why does crypt/blowfish generate the same hash with two different salts?

简短的回答是,正如 caf 所说,它使用由 [a-zA-Z0-9./] 组成的 base64 字母表,$ 作为空(非 0)终止/填充字符。如果您使用超出该范围的任何字符,或者太早使用 $,则会出错或无法解释整个 salt。

【讨论】:

以上是关于PHP crypt 和 salt - 请进一步说明的主要内容,如果未能解决你的问题,请参考以下文章

如何在 NODE.JS 上模拟 php crypt()

linux下c语言的crypt函数怎么用?

php 自带加密解密函数

为啥 PHP crypt 函数使用 DES 加密算法?

在 MacOS X 上使用 crypt 的 Python SHA512 加盐密码

PHP密码和token