如何获得真正的随机数据,而不是像 CSRNG 那样将随机数据送入 PRNG 种子?

How to get truly random data, not random data fed into a PRNG seed like CSRNG's do?

据我了解,像 RNGCryptoServiceProvider 这样的 CSRNG 仍然通过 PRNG 传递真正随机的用户数据,如鼠标移动等,以对输出进行排序并使其均匀分布。这些位需要完全独立。

(这是针对理论上无限算力的攻击者) 如果 CSRNG 取 1KB 的真正随机数据并将其扩展为 1MB,攻击者所要做的就是生成 1KB 数据的每个组合,扩展它,然后查看哪 1MB 数据生成一次性填充 returns 明智的英语输出。我在某处读到,如果一次一密在 RNG 中的任何地方都有一个 PRNG,那么它只是一个美化的流密码。我想知道真正随机的起始数据是否足够大,可以直接使用而不是加密扩展。我需要一次一密的真正随机输出,而不仅仅是加密安全的 RNG。或者,如果有其他方法可以以某种方式获得真正随机的数据,那么所有位都相互独立。我在考虑与鼠标坐标进行异或几秒钟,然后可能是 Environment.TickCount 的最后一位数字,然后可能还会获得麦克风输入 (1, 2, 3, 4)。然而,正如一些人在 Whosebug 上指出的那样,我真的应该让 OS 来处理这一切。不幸的是,这是不可能的,因为使用了 PSRNG。我想避免使用硬件解决方案,因为这是一个易于使用的程序,并且也不使用 RDRAND,因为它还使用 PRNG(除非 RDRAND 可以 return 真正的随机数据,然后再通过PRNG??)。如果这样的事情是可能的,将不胜感激;在 RNGCryptoServiceProvider 足以一次性完成的印象下,我已经为此工作了数周。谢谢

(旁注:有人说对于大多数加密函数,您不需要真正的熵,只需要不可预测性。对于一次性一密本,它必须是随机的,否则它不是一次性一密本。)

如您所知,“真正随机”意味着每个位 独立于其他一切 并且均匀分布。然而,这种理想即使不是不可能,也很难在实践中实现。一般来说,在实践中获得“真正随机数据”的最接近方法是从 nondeterministic sources 中收集 hard-to-guess 位,然后将这些位压缩成随机数据块。

要接近“真正的随机数据”涉及很多问题,包括:

  1. 来源必须是不确定的,也就是说,它们的输出不能由它们的输入决定。非确定性来源的例子包括输入设备的时间;热噪声;以及麦克风和相机输出记录的噪音。
  2. 消息来源的输出一定很难猜到。这更正式地称为 entropy,例如每 64 位输出有 32 位熵。然而,测量熵绝非易事。如果您需要 1 MB(800 万位)的真正随机数据,则需要具有至少 800 万位熵的数据(根据来源,实际上它的长度将超过 1 MB),然后压缩数据以某种方式转换为 1 MB 的数据,同时保留该熵。
  3. 来源必须相互独立。
  4. 应该有两个或更多的独立来源。这是因为不可能仅从一个来源提取完全随机性(参见 McInnes 和 Pinkas 1990)。另一方面,从三个或更多独立来源中提取随机性相对微不足道,但仍然存在选择合适的随机性提取器的问题,随机性提取器的调查将超出本答案的范围。

一般来说,为了生成随机数,可用的来源越多越好。

参考资料:

  • McInnes, J. L., & Pinkas, B.(1990 年 8 月)。关于使用弱随机密钥的私钥密码学的不可能性。在密码学理论与应用会议(第 421-435 页)中。