帮我理解pack(),openssl_random_pseudo_bytes()和mt_rand()来保存密码

jlm*_*kes 7 php random algorithm salt

我正在构建一个具有用户群的应用程序,而我正在确保登录安全.我是编程(和PHP)的新手,但到目前为止我的努力已经指向使用Crypt()和Blowfish哈希盐.

在我走得更远之前,让我指出此时对phpass不感兴趣.

crypt()文档中,用户最近发布了以下内容:

<?php 
   $salt = substr(str_replace('+', '.', base64_encode(pack('N4', mt_rand(), mt_rand(), mt_rand(), mt_rand()))), 0, 22); 
?>
Run Code Online (Sandbox Code Playgroud)

它适用于mt_getrandmax()== 2147483647的系统.

创建的salt长度为128位,填充为132位,然后以22 base64字符表示.(CRYPT_BLOWFISH只使用128位的盐,即使22个base64字符有132位.如果检查CRYPT_BLOWFISH输入和输出,你可以看到它忽略输入的最后四位,并在输出时将它们设置为零.)

注意,mt_rand()返回的四个32位双字的高位总是为零(因为mt_getrandmax == 2 ^ 31),所以128位中只有124位是伪随机的.我发现我的申请可以接受.

我测试了我的服务器,确实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,bit,byte等),但最后,如何实现与我的密码一起使用的相当安全的盐.

irc*_*ell 11

首先我要说的是,从生成的角度来看,盐没有什么特别之处.这只是另一个随机字符串.它的使用方式很特殊,但没有生成.

你的具体问题

  1. 为什么他替换+.

    我不知道.也许是因为+角色可能与网址中的空格混淆.但盐永远不应该在网址中,所以很可能不是.

  2. base64/hexdec做什么:

    Base64将原始字节流(每个字节的值从0到255)转换为基本64表示.它有很多资源,所以不值得深入研究.阅读维基百科文章了解更多信息.

    hexdec将十六进制数(a-f0-9)转换为十进制数.它从基数16转换为基数10(只是表示数字的另一种方式).

  3. 什么是位和字节:

    有点是一个单一的信息单位.它有2个状态,0或1.字节是一系列8位.所以一个字节可以有256个唯一的组合.阅读维基百科 ......

  4. 什么是ascii

    这是一个字符集.它表示单个8位字节中的单个可打印字符.我再次建议阅读维基百科.

盐一般

良好的盐生成功能的目标是大熵.这意味着可能的输出数量尽可能大.所以任何方法都应该产生大量的结果.

现在,您需要定义salt的可接受字符(因为您需要存储salt以验证哈希值).最好的盐是全字节数字,而不仅仅是可显示的字符.现在,您将无法在有意义的庄园中显示它,但您无需显示它.另外,对于存储,您可以随时使用base64_encode它.

接下来,您需要选择盐的浓度.盐越大越好.可以接受32个字符的盐,但是128个字符的盐更好.盐的大小和每个字符的选项数量将决定可能的数量.一些常见的组合:

Hex, 32 characters: 2e38 possibilities
Hex, 128 characters: 1e154 possibilities
Full Byte, 32 characters: 1e77 possibilities
Full Byte, 128 characters: 1e308 possibilities
Run Code Online (Sandbox Code Playgroud)

现在,您需要生成盐.关键是要根据需要进行多次随机调用以填写熵.你可以通过以下几种方式做到这一点

现在,您需要将其转换为所需的输出格式.