我可以从random_device和mt19937的组合生成加密安全的随机数据吗?

Avi*_*oss 7 c++ random cryptography mersenne-twister c++11

我需要在c ++ 11中生成加密安全的随机数据,我担心对所有数据使用random_device会严重限制性能(参见Stephan T. Lavavej的" rand()Considered Harmful "第23页,他说当他测试它(在他的系统上)时,random_device是1.93 MB/s而mt19937是499 MB/s)因为这个代码将在移动设备上运行(Android通过JNI和iOS),这可能比上面的数字慢.

另外我知道mt19937不是加密安全的,来自维基百科:"观察足够数量的迭代(在MT19937的情况下为624,因为这是生成未来迭代的状态向量的大小)允许一个预测所有未来的迭代".

考虑到上述所有信息,我是否可以通过mt19937的每624次迭代从random_device生成一个新的随机种子来生成加密安全的随机数据?或者(可能)更好,每X次迭代,其中X是1到624之间的随机数(来自random_device或者random_device播种的mt19937)?

Jer*_*fin 6

不要这样做.说真的,就是不要.这不仅仅是在寻找麻烦 - 更多的是通过进入你能找到的最危险城市中犯罪最多的部分,携带大量贵重物品来寻求和乞求麻烦.

我不建议经常重新播种MT 19937以掩盖它的不安全性,而是建议通过在计数器模式下运行AES来生成随机数.这要求您获得一个(但只有一个)正确大小的良好随机数,以用作您的发电机的初始"种子".

您可以将其用作AES的密钥,并使用它来加密序列号以获得看似随机但易于重现的输出流.

这有许多优点.首先,它使用的算法实际上已被大量研究,并且通常被认为是非常安全的.其次,这意味着你只需要分配一个(相当小的)随机数作为整个系统的"关键".第三,它可能提供更好的吞吐量.无论英特尔和(貌似)独立测试表明,开始时与你在低端报价什么MT 19937有竞争力的一系列吞吐量和高达约4-5倍的最高端得更快.鉴于你使用它的方式,我希望看到你得到的结果接近(甚至可能超过1)它们显示的范围的顶端.

结论:计数器模式下的AES显然是解决手头问题的更好方法.您可以期待的最好的是MT 19937最接近快速且接近安全.实际上,它可能会令这些希望失望,并最终导致速度变慢,安全性大大降低.


1.它将如何超过这些结果?毫无疑问,这些都是基于加密批量数据 - 即从RAM读取数据块,加密它,并将结果写回RAM.在您的情况下,您不需要从RAM中读取结果 - 您只需在CPU中生成连续的数字,加密它们并写出结果.


ros*_*sum 5

简短的回答是,不,你不能.加密安全RNG的要求非常严格,如果您在这里提出这个问题,那么您就不太了解这些要求.正如Jerry所说,如果您需要可重复性,AES-CTR是一种选择.另一个不允许重复性的选择是为您的系统寻找Yarrow或Fortuna的实现.一般来说,在库中找到CSRNG要比自己创建CSRNG好得多.图书馆作家充分了解的一个良好CSRNG的要求.