我需要在c ++ 11中生成加密安全的随机数据,我担心对所有数据使用random_device会严重限制性能(参见Stephan T. Lavavej'&#23的幻灯片23) 34; rand() Considered Harmful"他说,当他测试它(在他的系统上)时,random_device是1.93 MB / s而mt19937是499 MB / s)因为这个代码将在移动设备上运行(Android通过JNI和iOS)可能比上面的数字慢。
此外,我知道mt19937在加密方面不安全,来自wikipedia:"观察足够数量的迭代(在MT19937的情况下为624,因为这是生成未来迭代的状态向量)允许人们预测所有未来的迭代"。
考虑到上述所有信息,我是否可以通过mt19937的每624次迭代从random_device生成一个新的随机种子来生成加密安全的随机数据?或者(可能)更好,每X次迭代,其中X是1到624之间的随机数(来自random_device或者random_device播种的mt19937)?
答案 0 :(得分:6)
不要这样做。说真的,就是不要。这不仅仅是在寻找麻烦 - 更多的是通过进入你能找到的最危险城市中犯罪最严重的部分,携带大量贵重物品来寻求和乞求麻烦。
我没有尝试重新播种MT 19937以掩盖它的不安全性,而是建议通过在计数器模式下运行AES来生成随机数。这要求您获得一个(但只有一个)正确大小的良好随机数,作为您的发电机的初始“种子”。
您可以将其用作AES的密钥,只需使用它来加密序列号以获得看似随机的输出流,但很容易重现。
这有很多优点。首先,它使用的算法实际上已被大量研究,并且通常被认为是非常安全的。其次,这意味着你只需要将一个(相当小)的随机数作为整个系统的“关键”。第三,它可能提供更好的吞吐量。 Intel's和(貌似)independent tests都显示出一系列吞吐量,这些吞吐量与您在低端时针对MT 19937所引用的内容相比具有竞争力,并且在顶部的速度最高可达4-5倍结束。考虑到你使用它的方式,我希望看到你得到的结果接近(甚至可能超过 1 )它们显示的范围的顶端。
底线:计数器模式下的AES显然是解决手头问题的更好方法。您可以期待的最好的是MT 19937最接近快速且接近安全。实际上,它可能会令这些希望失望,并最终导致速度变慢,安全性大大降低。
<子> 1.它将如何超过这些结果?毫无疑问,这些都是基于加密批量数据 - 即从RAM读取数据块,加密它,并将结果写回RAM。在您的情况下,您不需要从RAM中读取结果 - 您只需在CPU中生成连续的数字,加密它们并写出结果。 子>
答案 1 :(得分:5)
简短的回答是,不,你不能。加密安全RNG的要求非常严格,如果您在这里提出这个问题,那么您就不能充分了解这些要求。正如Jerry所说,如果您需要可重复性,AES-CTR是一种选择。另一个不允许重复性的选项是为您的系统寻找Yarrow或Fortuna的实现。一般来说,在库中找到CSRNG要比自己创建CSRNG好得多。图书馆作家 充分了解良好CSRNG的要求。