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

时间:2015-06-04 17:54:41

标签: openssl erlang

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

有加密:strong_rand_bytes(N)。如果它抛出low_entropy异常怎么办?

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

  

strong_rand_bytes(N) - >二进制()

     

类型:N =整数()

     

随机生成N个字节均匀0..255,并在a中返回结果   二进制文件。使用加密安全的prng种子和定期   与操作系统混合提供熵。默认情况下,这是   OpenSSL中的RAND_bytes方法。

     

如果随机生成器失败,可能会抛出异常low_entropy   由于缺乏安全"随机性"。

我认为只是rand_bytes(N)的后退不是一个好方法。

1 个答案:

答案 0 :(得分:2)

  

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

首先处理不良状态处理它。你可以通过播种发电机来避免它。

您应该在启动时显式播种生成器。这避免了调用RAND_poll时的一些问题。对于某些问题,请参阅OpenSSL wiki上的Random Numbers

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

根据两篇论文(herehere),您应该在生成秘密之前添加熵。因此,您应在每次致电RAND_add之前致电RAND_bytes。在这种情况下,你永远不应该陷入糟糕的状态。

您也可以尝试RAND_status。如果它返回0,你应该为它提供另一个熵块。该块应至少为32个字节。种子生成器所需的熵量为purposefully hidden。请记住,随着时间的推移,值从16字节更改为32字节,因此线程使用旧值16。

我怀疑RAND_status在多线程环境中遭遇竞争,所以我不会依赖它。也就是说,状态可能会在调用RAND_statusRAND_bytes之间发生变化。

  

如果随机生成器由于缺乏安全的“随机性”而失败,可能会抛出异常low_entropy。

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

RAND_status可能会在异常之前返回0,在添加熵之后返回1。

但你不应该首先进入这种状态。

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

不要担心“攻击者可以看到对等密钥”或“传感器数据存在偏差”等问题。将提取熵并且混合器将其添加到状态,以便攻击者不会获得优势。

  

strong_rand_bytes(N) ...我想回退到rand_bytes(N) ......

我认为这就是古特曼和格里格斯所说的“加密数字学”。

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

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