我有一些关于使用加密安全伪随机数生成器 (CSPRNG) 的基本问题。
我初始化 CSPRNG 的种子的大小应该是多少?我应该多久重新播种一次?以及如何确定重新播种的熵的大小?
任何指针都会有所帮助。
我有一些关于使用加密安全伪随机数生成器 (CSPRNG) 的基本问题。
我初始化 CSPRNG 的种子的大小应该是多少?我应该多久重新播种一次?以及如何确定重新播种的熵的大小?
任何指针都会有所帮助。
重要的是熵。
使 PRNG 加密安全的原因是攻击者无法预测下一个字节。确切地说,在以下模型中定义了安全性的三个“安全级别”:
请注意,总是可以以 0.5 的概率(纯随机猜测)进行预测,因此我们需要的是攻击者不能做得更好。
一般来说,我们通常希望 PRNG 在k + e ≥ 128 的情况下满足这些属性。“128”是传统的限制。基本上,攻击者将尝试枚举可能的种子值,并查看与已知输出匹配的内容;如果攻击者找到了实际的种子,那么他可以以 100% 的准确率预测所有后续输出;否则,攻击者一无所知,并回到基于运气的猜测,即每个比特的概率为 0.5。
为了达到这个水平,种子应代表至少 128 位的熵。事实上,说“种子S的熵为 128 位”实际上意味着“攻击者尝试猜测S并以最佳顺序连续尝试猜测 S,从最可能的值开始,平均 2 127次尝试后将成功”。“平均”一词在这里很重要:熵是关于概率和平均值的。
要拥有 128 位的熵,您至少需要 128 位的数据,因为您无法将n位的熵放入少于n位的数据中。然而,现实生活中的“随机”数据是从物理测量中提取的,并且是有偏差的,因此需要更多的比特来表示。例如,您可以从用户的按键时间中获得一些随机性:从生物学上讲,用户无法重现精确到微秒的按键时间,因此两次按键之间的延迟(以纳秒表示)将“包含”大约 10熵位——但一秒的延迟需要 30 位以纳秒为单位进行编码。
一般来说,作为应用程序编写者,您不必进行估计熵的复杂工作:操作系统已经聚合了来自物理源的随机性,并计算了这些估计值。当您要求操作系统为您提供“随机字节”(通过/dev/urandom
在 Linux 系统上打开或CryptGenRandom()
在 Windows 上调用)时,您已经得到了充满时钟的熵。因此,要求 128 位(16 字节),您将获得足够好的 PRNG 种子。
(“128”是传统的。目前对最富有的攻击者的技术限制接近 2 75 次操作,并且在未来两三年内不太可能超过 2 100 次。“128”被密码学家认为是优雅的,因为它是2的幂。)
如果您的 PRNG 确实是加密安全的,则不需要重新播种 - 需要重新播种实际上算作中断,因此与 PRNG 加密安全的概念相矛盾。
许多人和标准仍然坚持重新播种,主要是因为一个既定的教条说你必须重新播种,原因实际上从未明确说明过。这个教条来自更早的时代,当时 PRNG不是加密安全的,实际上并没有在计算机上运行,因为那是在计算机发明之前。
因此,您应该尽可能频繁地重新设置种子以使您的审核员满意,但不要担心重新设置种子或不重新设置种子的安全问题:您重新设置种子不是为了获得更高的安全性,而是为了让其他人开心和安静。
(如果您的 CSPRNG 不是加密安全的,那么重新播种无论如何都不太可能挽救您的皮肤。)
我初始化 CSPRNG 的种子的大小应该是多少?
此处总结了批准的分组密码算法的种子长度和其他要求:
我应该多久重新播种一次?
只要攻击者不知道种子,它就是安全的。我想我不能比这个答案更好地解释了。
CSPNRG 熵是使用最小熵原理计算的。