【问题标题】:Cryptographically secure PRNG (PseudoRandom Number Generator)加密安全 PRNG(伪随机数生成器)
【发布时间】:2015-09-09 04:25:00
【问题描述】:

生成加密安全 PRNG 的最佳和最快算法是什么?我的要求如下。

  • 在每次运行中,我需要生成数百万个长度为 10 的数字。
  • 它不应该允许人们通过观察一些迭代来预测未来的迭代。
  • 数字应该是唯一的。不允许重复。
  • 速度也很重要,因为它会在每次迭代中生成数百万个数字。

我检查了Mersenne Twister 算法,但它似乎不是加密安全的。他们说,可以通过检查 624 次迭代来预测。

附:如果有Java实现就更好了。

【问题讨论】:

  • 投反对票的,请说明原因。
  • 使用 Java 的 SecureRandom。如果这还不够快,请在此处再次询问。
  • 伪随机数生成器总是可以预测的,因为它们使用确定性方法来生成数字。这就是为什么它们是 pseudo-随机的。您显然正在寻找的是real random number generator。这些通常使用hardware input,从鼠标移动和视频输入到衰变的放射性物质。
  • “数字应该是唯一的”。我想不出满足这一点的 any 随机数生成器,无论是否安全。 RNG 不可避免地会重复。
  • 永远不要推出自己的 RNG 或 Crypto。使用众所周知的、经过测试的、成熟的代码,并完全按照指示使用它。最简单、经过充分测试的加密 PRNG 是内置于您的操作系统中的那些:Linux 上的 /dev/random,Windows 上的 CryptGenRandom。 “没有重复”的事情是小数字(10位数字)的问题。如果您将它们设为 150 位(甚至可能是 100 位),您就可以避免重复。否则,您将不得不手动检查。当然……你到底想完成什么?我怀疑你根本不需要 CSPRNG。

标签: java algorithm random cryptography prng


【解决方案1】:

使用线性反馈移位寄存器。该算法快速且安全。 基于n次原始特征多项式构建寄存器。这将给出 2^n - 1 个唯一数字的序列。之后,该序列将重复。不要用零播种。一些著名的流密码算法基于 LFSR,因此您可以提取和研究实现。例如 LILI-128(但它在 C 中的参考实现)

【讨论】:

    【解决方案2】:

    您的独特要求意味着您不能使用任何类型的 RNG(我之前的评论是错误的),因为随机数将包括重复。相反,使用密码并加密数字:0、1、2、3,......这将保证唯一的结果。由于密码是可逆的,每个密文都解密回原始明文,因此密文是明文的排列。

    您还需要“长度为 10”的数字。我假设这意味着十进制数字,[1,000,000,000 .. 9,999,999,999]。这意味着您需要一个在 [0 .. 8,999,999,999] 范围内工作的密码,只需在输出中添加 1e9。

    那就更复杂了。要么使用Hasty Pudding cipher,它可以设置为你想要的任何数字范围,或者滚动你自己的Feistel cipher,其块大小设置为2的下一个更高的幂。如果数字超出范围,则重新加密直到它在范围内。 Feistel 选项会更快,但不太安全。您可以通过增加轮数来使其更安全,但代价是降低速度。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 2016-02-08
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    相关资源
    最近更新 更多