我想在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)的后退不是一个好方法。
答案 0 :(得分:2)
如何处理crypto的low_entropy异常:strong_rand_bytes(N)?
首先处理不良状态处理它。你可以通过播种发电机来避免它。
您应该在启动时显式播种生成器。这避免了调用RAND_poll
时的一些问题。对于某些问题,请参阅OpenSSL wiki上的Random Numbers。
你应该偶尔播种发电机。在这种情况下,请定期从/dev/urandom
读取并使用RAND_add
将其提供给生成器。并添加您可以获得的任何其他熵,例如您的同行的公钥或移动传感器数据。
根据两篇论文(here和here),您应该在生成秘密之前添加熵。因此,您应在每次致电RAND_add
之前致电RAND_bytes
。在这种情况下,你永远不应该陷入糟糕的状态。
您也可以尝试RAND_status
。如果它返回0,你应该为它提供另一个熵块。该块应至少为32个字节。种子生成器所需的熵量为purposefully hidden。请记住,随着时间的推移,值从16字节更改为32字节,因此线程使用旧值16。
我怀疑RAND_status
在多线程环境中遭遇竞争,所以我不会依赖它。也就是说,状态可能会在调用RAND_status
和RAND_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
猜测的机会。他们是一样的......