强制 OpenSSL 的 RNG 返回可重复的字节序列
对于加密实用程序的单元测试,我希望能够强制 OpenSSL 的加密随机数生成器(RAND_bytes
和 RAND_pseudo_bytes
)返回可预测、可重复的字节序列,因此各种密文反过来是可预测的,并且可以被烘焙到测试向量中。 (所有其他关键材料都在我的控制之下。)
我知道这完全破坏了安全性。这仅用于单元测试。
我不能在每次测试之前简单地使用固定种子调用RAND_seed
,因为(看起来)RNG 会自动从 /dev/ 为自己提供种子urandom
无论我是否想要它,无论如何,RAND_seed
不会重置 RNG,它只会将种子添加到熵池中。
有什么办法可以做到这一点吗? (在极端情况下,看起来我可以编写自己的 PRNG 引擎,但我想有一个更简单的选择。)
For unit tests of a cryptographic utility, I would like to be able to force OpenSSL's cryptographic random number generator (both RAND_bytes
and RAND_pseudo_bytes
) to return predictable, repeatable byte sequences, so that various ciphertexts are in turn predictable and can be baked into test vectors. (All other key material is under my control.)
I know this totally defeats security. This will only be used for unit tests.
I cannot simply call RAND_seed
with a fixed seed before each test, because (it appears) the RNG automatically seeds itself from /dev/urandom
whether I want it to or not, and anyway RAND_seed
doesn't reset the RNG, it only adds the seed to the entropy pool.
Is there any way to do this? (In extremis, it looks like I could write my own PRNG engine, but I'd like to think there's a simpler option.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以在运行时强制 FIPS ANSI X9.31 RNG 进入测试模式,但不能强制 SSLeay RNG(默认)。如果您使用
-DPREDICT
重新编译 OpenSSL,默认 RNG 将输出可预测的数字序列,但这不太方便。RAND_pseudo_bytes
函数生成一系列可预测的数字,这意味着它不会像RAND_bytes
那样自动向自身添加熵。但是就像您注意到的那样,只能向种子添加熵,而不能显式提供种子,因此在程序运行之间您将得到不同的数字。也没有帮助。但编写自己的可预测 RNG 引擎并不困难。事实上,我将通过制作一个以 stdlib 的
rand()
为核心的 rand 引擎来引导您完成它:每次运行此程序时,它都会播种
srand()
具有相同的数字,因此每次都会为您提供相同的随机数序列。You can force the FIPS ANSI X9.31 RNG into a test mode at runtime, but not the SSLeay RNG (the default). If you recompile OpenSSL with
-DPREDICT
, the default RNG will output a predictable sequence of numbers, but that's not very convenient.The
RAND_pseudo_bytes
function generates a predictable series of numbers, meaning it does not add entropy to itself automatically likeRAND_bytes
. But like you noticed it's only possible to add entropy to the seed, not provide the seed explicitly, so between runs of the program you'll get different numbers. Also not helpful.But writing your own predictable RNG engine is not difficult. In fact, I'll take you through it by making a rand engine with stdlib's
rand()
at its core:Every time you run this program, it seeds
srand()
with the same number and therefore gives you the same sequence of random numbers every time.围绕库编写一个包装器。然后在测试时将其替换为您自己的模拟,以返回您的神奇值。
请记住,在单元测试中您并不是要测试 OpenSSL。您正在尝试测试您的代码。
Write a wrapper around the library. Then substitute it at test time for your own mock that returns your magical values.
Remember, in a unit test you're not trying to test OpenSSL. You're trying to test your code.