zwo*_*wol 5 unit-testing openssl
对于加密实用程序的单元测试,我希望能够强制OpenSSL的加密随机数生成器(两者RAND_bytes和两者RAND_pseudo_bytes)返回可预测的,可重复的字节序列,以便各种密文可以预测并且可以烘焙到测试向量中.(所有其他关键材料都在我的控制之下.)
我知道这完全打败了安全.这仅用于单元测试.
我不能简单地RAND_seed在每次测试之前使用固定的种子进行调用,因为(看起来)RNG会根据/dev/urandom我是否需要它来自动播种,并且无论如何RAND_seed都不会重置 RNG,它只会将种子添加到熵池中.
有没有办法做到这一点?(在极端情况下,看起来我可以编写自己的PRNG引擎,但我想有一个更简单的选择.)
您可以在运行时强制FIPS ANSI X9.31 RNG进入测试模式,但不能强制使用SSLeay RNG(默认值).如果你重新编译OpenSSL -DPREDICT,默认的RNG将输出一个可预测的数字序列,但这不是很方便.
该RAND_pseudo_bytes函数生成一系列可预测的数字,这意味着它不会自动添加熵RAND_bytes.但是就像你注意到只能将熵添加到种子中,不能明确提供种子,所以在程序运行之间你会得到不同的数字.也没有帮助.
但是编写自己的可预测RNG引擎并不困难.事实上,我将通过制作一个以stdlib rand()为核心的rand引擎来引导你完成它:
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <openssl/rand.h>
// These don't need to do anything if you don't have anything for them to do.
static void stdlib_rand_cleanup() {}
static void stdlib_rand_add(const void *buf, int num, double add_entropy) {}
static int stdlib_rand_status() { return 1; }
// Seed the RNG. srand() takes an unsigned int, so we just use the first
// sizeof(unsigned int) bytes in the buffer to seed the RNG.
static void stdlib_rand_seed(const void *buf, int num)
{
assert(num >= sizeof(unsigned int));
srand( *((unsigned int *) buf) );
}
// Fill the buffer with random bytes. For each byte in the buffer, we generate
// a random number and clamp it to the range of a byte, 0-255.
static int stdlib_rand_bytes(unsigned char *buf, int num)
{
for( int index = 0; index < num; ++index )
{
buf[index] = rand() % 256;
}
return 1;
}
// Create the table that will link OpenSSL's rand API to our functions.
RAND_METHOD stdlib_rand_meth = {
stdlib_rand_seed,
stdlib_rand_bytes,
stdlib_rand_cleanup,
stdlib_rand_add,
stdlib_rand_bytes,
stdlib_rand_status
};
// This is a public-scope accessor method for our table.
RAND_METHOD *RAND_stdlib() { return &stdlib_rand_meth; }
int main()
{
// If we're in test mode, tell OpenSSL to use our special RNG. If we
// don't call this function, OpenSSL uses the SSLeay RNG.
int test_mode = 1;
if( test_mode )
{
RAND_set_rand_method(RAND_stdlib());
}
unsigned int seed = 0x00beef00;
unsigned int rnum[5];
RAND_seed(&seed, sizeof(seed));
RAND_bytes((unsigned char *)&rnum[0], sizeof(rnum));
printf("%u %u %u %u %u\n", rnum[0], rnum[1], rnum[2], rnum[3], rnum[4]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
每次运行此程序时,它都会srand()以相同的数字播种,因此每次都会为您提供相同的随机数序列.
corruptor:scratch indiv$ g++ rand.cpp -o r -lcrypto -g
corruptor:scratch indiv$ ./r
1547399009 981369121 2368920148 925292993 788088604
corruptor:scratch indiv$ ./r
1547399009 981369121 2368920148 925292993 788088604
corruptor:scratch indiv$
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1988 次 |
| 最近记录: |