加密和比较哈希值

时间:2017-08-13 10:15:00

标签: php security encryption hash

检查了很多关于StackOver上的加密和散列的教程和指南,我现在明白了它们之间的区别。 我们需要解密时加密。你不要哈希(例如:密码)。

但我今天的问题是,用于生成随机唯一令牌。很多人建议使用base64_encode(rand_bytes(32));因为它会产生一个带有随机字节/字母的安全密码id,因此需要很长时间才能被强力破解(需要预测)。

但是当你,例如,hash_hmac或crypt这个id会让它变弱吗? 如果是这样,使用mt_rand或random_bytes无关紧要,因为它会生成其他字母/ id。所以你们推荐什么?

另外,crypt是否比hash_hmac更好用于散列?

最后一个问题,由于blowfish有一个非常强大的哈希算法,我是否需要存储我的PHPSESSID或CSRF令牌,或者只是普通的random_bytes?

请大家,向我提供有关这些问题或文档的详细信息。 抱歉我缺乏信息和经验不足,我是PHP编码的新手,谢谢!

编辑:我在SO上看过一些指南,并没有涵盖我的所有问题,所以我需要2017年的详细信息,而不是10年前的帖子,其中md5是最好的......等。

3 个答案:

答案 0 :(得分:2)

当您只想要无法预测的令牌时,请使用random_bytes(32) 只要您保持令牌秘密,就没有理由改变结果这个功能。

  

但是你问了很多具体的问题,所以我会尽力回答:

当您散列或crypt()该ID会使其变弱时?

这取决于HMAC或crypt例程。当您生成32个字节的随机数据,然后使用函数将大小减小到16个字节时,安全性将减半。但是,如果使用具有至少32个字节输出的加密安全函数,则不会降低安全性。现在我这样说,因为 crypt()不是加密安全功能在对密码进行散列处理时,请改为使用password_hash()

使用mt_rand和使用random_bytes

之间有区别吗?

是的,重要。 mt_rand()使用Mersenne Twister随机数生成器。这些都不安全。这意味着攻击者可以使用令牌值来猜测其他令牌。在mt_rand()的情况下,这通常很容易。如果您需要令牌是安全的(身份验证令牌,会话cookie,CSRF令牌,可能无法枚举的ID等),请使用random_bytes。另外,如果您不确定,请使用random_bytes

另外,crypt是否优于hash_hmac进行散列?

不。 Crypt已弃用,您不应使用它。需要消息验证代码时使用HMAC(例如密码重置URL)。对于密码哈希,请使用password_hash

我是否需要将我的,例如PHPSESSID或CSRF令牌与Blowfish或普通random_bytes存储?

只需使用random_bytes即可。随机数据已经是随机的,不需要再次随机化。至少,只要你保密这些代币并在它们泄露时立即撤销它们。

答案 1 :(得分:2)

散列不能使你的标记更强或更随机,没有办法增加真正随机标记的熵或改进它。否则就会改进它。

散列令牌的唯一时刻是有道理的,就是它存储在会话/数据库中时(客户端总是应该获取原始令牌)。在数据库中存储哈希将在数据被盗的情况下保护令牌(SQL注入)。

与“弱”用户密码相比,“强”随机令牌无法成功强制执行,因此不需要进行腌制和键拉伸。可以使用简单的快速哈希函数,如SHA-256,它可以搜索哈希值。当客户端发出请求时,可以再次对原始令牌进行哈希处理,并搜索存储的哈希值。

答案 2 :(得分:-1)

@martinstoeckli兄弟,你太棒了,当你深刻解释一切时,我理解你所描述的一切。为了确保我清楚,请检查我的代码!

1-)没有哈希值且没有存储在像CSFR令牌这样的数据库中的随机令牌

$random_code = base64_encode(random_bytes(32)); //without hashing

2-)记住我 - 客户端将拥有random_code,并且在数据库中,我存储了哈希令牌。

remember_me的例子

$random_code = base64_encode(random_bytes(32));

            $token = hash_hmac('sha256', ($random_code . $username) , $random_code);
            $token = hash_hmac('sha256', $random_code , $token);


      setcookie("remember", $username . "|" . $random_code, time()+(60 * 60 * 24 * 7), "/", "", 1, 1); //1 week