假设我想为用户创建一个 cookie。只需使用/dev/urandom生成一个 1024位字符串,并检查它是否已经存在(循环直到我得到一个唯一的字符串)就足够了吗?
我应该根据其他东西生成密钥吗?这是否容易以某种方式被利用?
假设我想为用户创建一个 cookie。只需使用/dev/urandom生成一个 1024位字符串,并检查它是否已经存在(循环直到我得到一个唯一的字符串)就足够了吗?
我应该根据其他东西生成密钥吗?这是否容易以某种方式被利用?
简短的回答是肯定的。长答案也是肯定的。/dev/urandom
在现有技术的情况下,产生的数据与真正的随机性无法区分。获得比所提供的“更好”的随机性/dev/urandom
是没有意义的,除非您使用为数不多的“信息论”密码算法之一,这不是您的情况(您会知道的)。
手册页urandom
有点误导,可以说是完全错误的,当它暗示/dev/urandom
可能“耗尽熵”并且/dev/random
应该被首选时;由于低熵而/dev/urandom
可能暗示安全问题的唯一时刻是在全新的自动化操作系统安装的最初时刻;如果机器启动到开始有一些网络活动的程度,那么它已经收集了足够的物理随机性来为所有实际用途提供足够高质量的随机性(我在这里谈论的是 Linux;在 FreeBSD 上,那一瞬间的轻微根本不会出现弱点)。另一方面,/dev/random
有在不合时宜的时候阻塞的趋势,导致非常真实和令人讨厌的可用性问题。或者,用更少的话来说:使用/dev/urandom
而且要快乐; 使用/dev/random
并感到抱歉。
(编辑: 这个网页非常清楚地解释了两者之间的区别/dev/random
。 )/dev/urandom
出于产生“cookie”的目的:这样的 cookie 应该不会有两个用户共享同一个 cookie,并且任何人在计算上都不可能“猜测”现有 cookie 的值。一个随机字节序列做得很好,只要它使用足够质量的随机性(/dev/urandom
很好)并且它足够长。根据经验,如果您的用户少于2 n 个(如果整个地球人口都可以使用您的系统,则n = 33 ),那么n+128位的序列就足够宽了;您甚至不必检查与现有值的冲突:您一生都不会看到它。161 位适合 21 个字节。
如果您想要更短的 cookie 并且仍希望避免在数据库中查找冲突,则有一些技巧是可行的。但这对于 cookie 来说几乎不是必需的(我假设是基于 Web 的上下文)。此外,请记住对您的 cookie 保密(即使用 HTTPS,并将 cookie 设置为“安全”和“HttpOnly”标志)。
是的,这是一个很棒的方法。
@Thomas 的解释说明了这一点。/dev/urandom
他批评手册页是完全正确的。发现。
但跳过“检查它是否已经存在”。那个检查是没有意义的。它不会发生。(发生这种情况的可能性低于在同一天多次被闪电击中的可能性。)
如果您使用的是 Linux 或 NetBSD,请注意边缘情况。
在 Linux 上,您需要确保在启动后获得了足够的熵以正确地为 CSPRNG 播种,或者使用getrandom()
系统调用来读取/dev/urandom
并仅在启动后初始种子熵不可用的极少数情况下阻塞。
在 NetBSD 中,您需要在读取 from/dev/random
之前至少读取一次,/dev/urandom
以确保它已正确播种。
/dev/random
在 FreeBSD 和 MacOS 上,和没有区别/dev/urandom
。
简短的回答仍然是使用/dev/urandom
.
有关详细信息,请参阅何时使用 /dev/random 与 /dev/urandom。
来自http://www.linuxfromscratch.org/hints/downloads/files/entropy.txt “在计算机中生成真正的熵相当困难,因为除了量子物理之外,没有什么是随机的。Linux 内核使用键盘、鼠标、网络, 和磁盘活动,使用加密算法 (SHA1) 为 /dev/random 设备生成数据。这样做的问题之一是输入不是恒定的,因此内核熵池很容易变空。” “使用键盘、鼠标、网络和磁盘活动的另一个问题是,在空闲、无人和无磁盘系统上,此类输入很少或根本没有。”
对我来说, /dev/urandom 看起来真的很有可能会用完,因为 /dev/random 提供了它。