很多代码都是这样做的,以产生某种秘密:
sha1(random())
为什么不简单地使用随机数?我意识到,在过去,一些操作系统随机生成器并不是那么好,但我不确定它是否仍然是真的,即使它是,但它是如何实现的它更好吗?
答案 0 :(得分:2)
如果您正在生成秘密,则应使用加密安全的随机数或伪随机数生成器。散列非密码安全的随机数是一种默默无闻的安全形式,而不是真正的安全措施。
它增加了一个计算秘密的步骤,这可能就是它完成的原因,但它并没有使秘密安全。
答案 1 :(得分:2)
我怀疑哈希函数通常被误用为编码函数。需要一定长度的字母数字代码,并且散列提供这样的字符串。它很简单,看起来不可预测。
很容易忘记,md5(random())
的随机部分不是md5的32个十六进制字符,而是只有random()
函数提供的可能结果。如果知道随机函数如何工作,可以预先计算一系列可能的值。
如果您真的使用了OS的随机源,并且请求尽可能多的字节,那么代码将更随机(更好的熵)。然后,您可以使用base64_encode()
之类的函数对这些字节进行编码。对于令牌,base62编码是理想的,因为它非常紧凑并且不返回特殊字符,尽管它有点难以实现。
回答你的问题:一个随机数会更好,但它必须“真正”随机。如果你将它用作只有'0' - '9'的字母数字,那么你的令牌会很长,可以用编码功能缩短它。
答案 2 :(得分:0)
您不希望使用随机数而不是哈希值,因为攻击者更容易猜测您的源并创建自己的“秘密”(特别是如果您使用系统时钟,请不要这样做。)见Is using microtime() to generate password-reset tokens bad practice)。从随机化的角度来看,真正的随机数并不比随机数的散列更好,但它模糊了模式,使得人类无法识别任何变化模式(例如种子值)。此外,它确实增强了安全性,因为当攻击者必须在提交之前散列每次尝试时,暴力攻击需要更长的时间。对于像SHA-256这样的强哈希,尤其如此。当每次提交需要处理器密集型操作时,暴力攻击所需的计算时间量会显着增加。这就是Linux将密码哈希存储为MD5到SHA的原因。
此外,SHA和其他哈希具有一些有益于安全性的数学优势。首先,无论输入长度如何,它们总是输出相同的长度。其次,输入的微小变化导致输出的大的变化,并且对于输出的小的变化,获得该输出所需的相应输入将比先前的输入差异更多。这使得攻击者很难通过选择性地输入输入来生成他们想要的哈希,并且这使得两个类似输入几乎不可能产生相同甚至非常接近的输出。
这是一个深刻的话题,可以写一本关于它的整本教科书,但这些只是一些高级别的原因。