有多少比特的熵
SELECT SHA2(RAND(), 256);生成?
(实际问题:这是一种为密码生成随机盐的合理方式吗?)
发布于 2013-05-29 00:03:01
让我们来分析一下。
SHA2可以指以下4种算法之一:
SHA224 - 224位outputSHA256 - 256位outputSHA384 - 384位outputSHA512 - 512位输出因此,它们每个都接受任意输入(0到2^64-1位数据),并产生固定大小的输出。
请注意,这里实际上没有创建熵。然而,当输入比输出大小更多的熵时,一些熵就会被破坏。当我们考虑到碰撞的(小)可能性时,有时小于输出大小的输入可能会有熵被破坏。因此,我们可以说,每个函数都将熵的上限作为其输出大小。
所以哈希不能增加熵。这意味着我们的熵上限是散列的输出大小和输入大小中的较小者。
现在,您的输入是RAND()。假设您引用的是MySQL的RAND()函数,让我们看看发生了什么。RAND()函数产生一个浮点数结果。现在,对于FLOAT数据类型,MySQL使用4字节的浮点值。这意味着,结果最多包含32位熵。
因此,组合已经下降到 32位熵的上限。
多亏了32位熵的Birthday Paradox,我们有50%的概率在7000代内发生碰撞。对于一个有效的盐来说太低了..。
这甚至没有触及RAND()是可预测的这一事实(对于盐的情况,这并不是世界末日)。
相反,只需使用一个库来为您处理生成。在PHP中,我建议使用password-compat或phpass。
在其他语言中,我不确定。但说真的,不要重新发明它。只需使用一个库(最好是使用bcrypt或scrypt的库),并完成它。
发布于 2013-05-27 15:28:30
散列函数SHA2不会向结果盐中添加任何熵,它只是将rand()的结果转换为另一种形式。这意味着,一切都依赖于rand()函数及其实现。
函数rand()当然不是随机的,如果你知道函数的状态(最后一个结果),你就可以预测下一个生成值。状态本身基于种子,有时此种子由应用程序自动设置。例如,PHP根据当前时间和process-id创建一个种子。请注意,这些值在某种程度上也是可预测的,或者至少会缩小可能结果的范围。
我不知道rand的MYSQL实现,但我不建议使用它的rand()函数来生成盐。实际上,我永远不会让数据库生成密码的盐值或散列值,因为大多数数据库都不提供适当的散列密码的方法。而不是使用具有缓慢的密钥派生函数(如BCrypt )的开发环境,此类函数通常会自动创建安全的salt。
为了回答你的问题,唯一性是盐的主要目的,所以有一些较弱的方法来生成盐。最好是一个不可预测的盐,这样就没有人可以预先计算出盐(可能的盐的范围),从而可以准备攻击。获得salt的最好方法是,使用操作系统的随机源(URANDOM)。
https://stackoverflow.com/questions/16766282
复制相似问题