如何处理 low_entropy crypto:strong_rand_bytes(N) 的异常?

how to handle low_entropy exception of crypto:strong_rand_bytes(N)?

我想在 erlang 中为会话 ID 生成加密强度高的伪随机数。

有crypto:strong_rand_bytes(N)个。如果抛出 low_entropy 异常怎么办?

来自http://www.erlang.org/doc/man/crypto.html#strong_rand_bytes-1

strong_rand_bytes(N) -> binary()

Types: N = integer()

Generates N bytes randomly uniform 0..255, and returns the result in a binary. Uses a cryptographically secure prng seeded and periodically mixed with operating system provided entropy. By default this is the RAND_bytes method from OpenSSL.

May throw exception low_entropy in case the random generator failed due to lack of secure "randomness".

我想回退到 rand_bytes(N) 不是一个好方法。

how to handle low_entropy exception of crypto:strong_rand_bytes(N)?

首先不要进入不良状态来处理它。您可以通过为生成器播种来避免它。

您应该在启动时明确为生成器设定种子。这避免了调用 RAND_poll 时出现的一些问题。对于某些问题,请参阅 OpenSSL wiki 上的 Random Numbers

您应该偶尔为生成器播种。在这种情况下,定期从 /dev/urandom 读取并使用 RAND_add 将其提供给生成器。并添加您可以获得的任何其他熵,例如您同伴的 public 密钥或移动传感器数据。

根据两篇论文(这里这里),你应该在生成秘密之前添加熵。所以你应该在每次调用RAND_bytes之前调用RAND_add。在这种情况下,你永远不应该进入糟糕的状态。


您也可以尝试 RAND_status. If it returns 0, you should supply it with another block of entropy. The block should be at least 32 bytes. The amount of entropy needed to seed the generator is purposefully hidden。请记住,该值随时间从 16 字节变为 32 字节,因此线程使用旧值 16。

我怀疑RAND_status suffers a race in a multithreaded environment, so I would not depend on it. That is, status could change between the call to RAND_status and RAND_bytes


May throw exception low_entropy in case the random generator failed due to lack of secure "randomness".

在这种情况下,捕获异常,向生成器添加 32 个字节,然后重试操作。

RAND_status 可能 return 异常前为 0,添加熵后为 1。

但你一开始就不应该进入这种状态。


你应该为你的发电机提供任何你手上的熵,even less than perfect ones. The more redundancy, the better。有些人想争论是否使用 /dev/random 还是 /dev/urandom 还是 /dev/srandom。我真的不在乎,只要有足够的熵 - 我正在使用 /dev/random/dev/urandom、对等 public 密钥、时间、PID 和来自移动设备的传感器读数。

不用担心 "the attacker can see the peer key" 或 "sensor data is biased" 之类的事情。熵将被提取出来,混合器会将其添加到状态中,这样攻击者就不会获得优势。


strong_rand_bytes(N) ... I guess a fallback to just rand_bytes(N) ...

我认为这就是 Gutmann 和 Griggs 所说的 "crypto-numerology"。

假设您可以捕获物理事件,并假设您可以使用提供 256 位安全性的加密原语从生成器读取数据。那么,假设你需要32字节的数据。

给你 32 个字节的随机过程和给你 32 个字节的基于加密的生成器之间没有区别。对于物理过程,攻击者只能猜测,所以他们有 1 / 2^256 的猜测机会。使用加密原语,攻击者有 1 / 2^256 的猜测机会。他们是一样的...