【发布时间】:2011-06-24 13:00:24
【问题描述】:
我正在构建一个拥有用户群的应用程序,并且我正处于保护登录的阶段。我对编程(和 PHP)还很陌生,但到目前为止,我的努力指向使用 Crypt() 和 Blowfish 散列盐。
在我继续之前,让我说明一下我目前对 phpass 不感兴趣。
在crypt() 文档中,一位用户最近发布了以下内容:
<?php
$salt = substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 22);
?>
它旨在用于系统 其中 mt_getrandmax() == 2147483647。
创建的盐将是 128 位 长度,填充到 132 位,然后 以 22 个 base64 字符表示。 (CRYPT_BLOWFISH 仅使用 128 位 盐,即使有 132 22 个 base64 字符中的位。如果你 检查 CRYPT_BLOWFISH 输入和 输出,你可以看到它忽略了 输入的最后四位,并设置 它们在输出时为零。)
请注意, 由返回的四个 32 位双字 mt_rand() 将始终为零(因为 mt_getrandmax == 2^31),所以只有 124 个 128 位将是伪随机的。一世 发现我可以接受 应用。
我测试了我的服务器,并且确实 mt_getrandmax() 返回 2147483647。我尝试查看文档以了解上述代码的实际作用——pack() 代码 N4 用于 32 位字符串(大端字节序??) 重复 4 次...我认为这就是为什么有 4 个 mt_rand() 参数。
我不明白的是他为什么用. 替换+ 以及22 个base64 字符的用途(并不是我完全理解base64 是什么。)
建议我查看openssl_random_pseudo_bytes() 来生成随机盐,因为我之前查看的方法仅限于1234567890abcdefghijklmnopqrstuvwxyz。
据说5.3.4 之前存在一个错误,导致openssl_random_pseudo_bytes() 运行缓慢,偶尔会导致超时错误。我不确定我是否应该尝试将openssl_random_pseudo_bytes() 与Crypt() 一起使用,或者类似于上述使用mt_rand() 和pack() 的方法。
我试图更多地了解所有这些元素是如何工作的,以及它们在概念上的作用——而不是仅仅使用一个而不理解它来实现我的目标;我正在努力学习:P
有人可以帮助我了解这里工作的不同元素,或者至少将我引导到一个我可以阅读它的知识库吗?我认为最难理解的部分是理解不同的格式/术语(base64、ascii、hexdec、位、字节等),但最终,如何获得相当安全的盐以用于我的密码。
【问题讨论】: