【问题标题】:How can a pseudorandom number generator possibly be non-repeating?伪随机数生成器怎么可能是不重复的?
【发布时间】:2016-12-14 18:39:43
【问题描述】:

我的理解是 PRNG 的工作是使用输入种子和将其转换为非常不相关的输出的算法,以便下一个生成的数字尽可能不可预测。但这是我看到的问题:

我能想象到的任何伪随机数生成器都必须有有限数量的结果。假设我正在使用一个随机数生成器,它可以生成 0 到 1000 亿之间的任何数字。如果我要求输出一千亿和一次,我可以确定一个数字已经输出了不止一次。如果相同的种子在通过算法时总是给出相同的输出,那么我可以确定 PRNG 将开始一个循环。我的逻辑哪里有缺陷?

如果我是正确的,如果你知道 PRNG 的算法,并且 PRNG 被用于加密,那么不能使用这种方法(并且有任何措施来防止它吗?):

  • 使用 PRNG 生成可能的整个循环数字集。
  • 知道生成私钥的时间戳,然后知道 PRNG 的时间 AND 输出
  • 根据计算所需的时间,确定已知输出和未知输出之间有多少个数字
  • 在预先生成的列表中查找生成的号码

【问题讨论】:

  • “使用 PRNG 生成可能的整个循环数字集”。如果你能等上 10^100 年,当然,去吧。
  • 请记住,状态不必与输出的大小相同。即使您只获得 32 位输出或 64 位输出,状态也可能是 256 位,太大而无法等待它循环。
  • @user2357112 而不是循环,该算法可以只向状态添加更多位,使其在每秒十亿次输出的情况下再过数十亿年,然后才会有重复的风险。

标签: algorithm random


【解决方案1】:

你是绝对正确的,理论上这种方法可以用来破坏 PRNG,因为,正如你所指出的,给定足够长的输出序列,你可以开始预测接下来会发生什么。

问题是“足够长”可能太长了,以至于这种方法完全不切实际。例如,Mersenne twister PRNG,它不是为加密使用而设计的,它的周期为 219,937 - 1,这个周期太长了,你完全不可能尝试攻击描述。

一般来说,假设一个伪随机生成器使用 n 位内部存储。这为这些位提供了 2n 种可能的内部配置,这意味着您可能需要看到 2n + 1 个输出,然后才能保证看到重复。鉴于大多数加密安全 PRNG 使用至少 256 位的内部存储,这使得您的攻击不可行。

值得注意的一个细节是,“PRNG 重复一个数字”和“从那时起,数字将始终相同”之间存在差异。 PRNG 可能会重复输出多次,然后再继续输出不同的数字,前提是每次内部状态都不同。

【讨论】:

    【解决方案2】:

    你是对的,PRNG 产生一长串数字然后重复。对于普通用途,这通常就足够了。正如您所指出的,不用于加密。

    对于理想的密码数,我们需要使用真正的 RNG (TRNG),它会从某种熵源(在此上下文中为随机性)生成随机数。这种源可能是卡上的一小块放射性物质、断开的麦克风电路中的热噪声或其他可能性。许多不同来源的混合将更能抵抗攻击。

    通常此类熵源不会产生足够的随机数以供直接使用。这就是 PRNG 用于“拉伸”真实熵的地方,以从 TRNG 提供的较少量的熵中产生更多的伪随机数。熵用于播种 PRNG,PRNG 基于该种子产生更多的数字。允许的拉伸量是有限的,因此攻击者永远无法获得足够长的伪随机数串来进行任何有价值的分析。达到限制后,必须从 TRNG 重新播种 PRNG。

    此外,PRNG 应该在每次数据请求后重新播种,无论多么小。有各种加密原语可以帮助解决这个问题,例如哈希。例如,在每个数据请求之后,可以生成另外 128 位数据,与任何可用的累积熵进行异或运算,然后进行散列处理,并将生成的散列输出用于重新生成生成器。

    加密 RNG 比普通 PRNG 慢,因为它们使用慢速加密原语,并且因为它们采取了额外的预防措施来抵御攻击。

    有关 CSPRNG 的示例,请参阅 Fortuona

    【讨论】:

      【解决方案3】:

      可以在 PC 上创建真正的随机数生成器,因为它们是不确定的机器。

      确实,随着分层内存层次的复杂性、CPU 管道的错综复杂、无数进程和线程在任意时刻激活并竞争资源并存,以及 I/O 设备的异步性,没有执行的操作数量和经过的时间之间的可预测关系。

      所以不时查看系统时间是完美的源随机性。

      【讨论】:

      • 这很有趣,但它真的回答了这里的问题吗?此外,虽然我同意您肯定可以从计算机的不同来源中获取大量熵,但定期查看系统时间似乎是一个非常糟糕的主意,因为攻击者可以很容易地猜出您正在运行的时间窗口并暴力破解- 强制攻击该范围内所有可能的时间以猜测您使用的种子。
      • @templatetypedef:祝你好运破解一个有 128 个普通状态位加上 16 个真正随机的生成器,通过每十亿次操作探测时钟获得(保守数字)。
      • 我可能误解了你的说法。通常认为将系统时间用于加密应用程序是一个坏主意,因为如果这些是唯一的种子位,它们可以相对容易地被暴力破解,因为没有那么多不同的可能值(至少,与可能的空间相比)键)。但是,如果您只是将它们用作一般熵累加器中的一个熵源,那么是的,这是一种完全合理的方法。 (不过,我仍然认为您的回答并未真正回答问题。)
      • @templatetypedef 不在现代 CPU 上,其 TSC 以每秒数十亿滴答的速度运行,您可以随时检查。您必须知道自己在做什么,但可以构建真正的随机数生成器,而且经常如此。
      • 使用计时器点击是一点熵的有效来源。单靠它是不够的。它需要与其他熵源相结合,并将全部散列在一起以提供合理的随机输入。
      【解决方案4】:

      我能想象到的任何伪随机数生成器都必须有有限数量的结果。

      我不明白为什么这是真的。为什么它不能有逐渐增加的状态,当它耗尽内存时失败?

      这是一个从不重复的简单 PRNG 算法:
      1) 以攻击者未知的任何数据量作为种子的种子。
      2) 计算数据的 SHA512 哈希值。
      3) 输出该哈希的前 256 位。
      4) 将该哈希的最后一个字节附加到数据中。
      5) 转到第 2 步。

      而且,出于实际目的,这并不重要。只需 128 位状态,您就可以生成一个不会重复 340282366920938463463374607431768211456 输出的 PRNG。如果你在 10 亿年内每秒拉出 10 亿个产出,你将无法完成其中的十亿个。

      【讨论】:

      • 状态不是还是有限的吗?它似乎不可能字面上永远不会重复。即使这是一个荒谬的长时间,最终状态也会变成同样的东西并且它会循环。 (我知道对于所有实际用途都没有关系,只是想知道它在理论上是否会)
      • 由于状态每次都长一个字节,它怎么能重复?
      • 就像你说的,当你用完内存时它会失败,如果你想让它继续生成数字,你就必须从别的地方开始。最终,您不会两次获得相同的值吗?
      • @Ekyl 如果内存不足,它将失败。但是每个算法都有计算要求,如果一个系统不能满足它的要求,那个算法就会失败。但它永远不会重复,只要硬件足以支持算法。
      • @Ekyl 你是对的,有限的计算机不可能产生无限的非周期序列。在实践中,这意味着很少。我们不需要非周期序列,具有极长周期的序列足以满足我们的目的。
      猜你喜欢
      • 2016-03-08
      • 2011-07-02
      • 1970-01-01
      • 2014-03-21
      • 1970-01-01
      • 2012-02-09
      • 1970-01-01
      • 2014-05-18
      • 2016-10-23
      相关资源
      最近更新 更多