开源polarssl加密库使用详解之二:伪随机数发生器(DRBG)

        随机数在密码学中的具有十分重要的地位,被广泛用于密钥产生、初始化向量、时间戳、认证挑战码、密钥协商、大素数产生等等方面。随机数产生器就是用于产生随机数的算法、函数以及设备。因此它的安全性也就对密码系统的安全性带来重要影响。随机数产生器包括非确定性(真随机)数产生器(Non-deterministic Random Bit Generators (NRBG))和确定性(伪随机)数产生器(Deterministic Random Bit Generators (DRBG))两类。真随机数产生器一般基于物理或化学熵源,比如原子运行轨迹、环境噪音、电路噪声,空气中颗粒数等等,这种随机数产生器的特点是随机性非常好,完全不可预测和回溯,但这些方法一般需要依靠特定的物理系统环境条件才能获取,所以应用范围有限。一般系统使用的随机数产生器都是伪随机的。伪随机数产生器之所以被称为确定性随机数产生器,是因为在确定输入(种子)的情况下,它的输出也就确定了,相同的输入必然导致相同的输出,这类随机数产生器一般只依赖软件算法实现,对系统要求较低,应用范围广泛。

根据NIST SP800-90 标准算法,提供了4 种标准算法。即,Hash_DRBG、HMAC_DRBG、CTR_DRBG、Dual_EC_DRBG。在polarssl中提供了两种随机数产生的方法

1)HAVEGE(HArdware Volatile Entropy Gathering and Expansion) 随机数发生器,实现的具体代码在havege.c这个文件。

注意:默认的编译是没有开启它的,你需要在config.h这个文件中定义宏POLARSSL_HAVEGE_C,此外HAVEGE随机生成是依赖于时间和具体处理器的特性,因此,不建议使用HAVEGE作为你的应用程序的主要随机数发生器或主熵池输入。它能够添加(有限)额外的熵,作为辅助输入到你的熵池。HAVEGE不能使用在虚拟环境中。

下面介绍HAVEGE 的使用方法

int main( int argc, char *argv[] )
{
    FILE *f;
    time_t t;
    int i, k;
    havege_state hs;
    unsigned char buf[1024];
    if( argc < 2 )
    {
        fprintf( stderr, "usage: %s <output filename>\n", argv[0] );//arg[1]是生成的数据存放的文件名字
        return( 1 );
    }
    if( ( f = fopen( argv[1], "wb+" ) ) == NULL )
    {
        printf( "failed to open '%s' for writing.\n", argv[0] );
        return( 1 );
    }
    havege_init( &hs );
    t = time( NULL );
    for( i = 0, k = 768; i < k; i++ )
    {
        if( havege_random( &hs, buf, sizeof( buf ) ) != 0 )//产生一个havege随机数,随机数的长度是sizeof(buf)字节
        {
            printf( "Failed to get random from source.\n" );
            fclose( f );
            return( 1 );
        }
        fwrite( buf, sizeof( buf ), 1, f );
        printf( "Generating 32Mb of data in file '%s'... %04.1f" \
                "%% done\r", argv[1], (100 * (float) (i + 1)) / k );
        fflush( stdout );
    }
    if( t == time( NULL ) )
        t--;
    printf(" \n ");
    fclose( f );
    return( 0 );
}
关于haveged的具体实现算法,这里不做介绍,有兴趣的朋友可以去研究一下。本博文介绍了其使用方法。


2)CTR_DRBG随机数发生器,它是基于分组密码函数的确定性随机数产生器,如图(NIST SP800-90中定义起标准算法)。




下面介绍polarssl中如何使用CTR-DRBG

int main( int argc, char *argv[] )
{
    FILE *f;
    int i, k, ret;
    ctr_drbg_context ctr_drbg;
    entropy_context entropy;
    unsigned char buf[1024];
    if( argc < 2 )
    {
        fprintf( stderr, "usage: %s <output filename>\n", argv[0] );
        return( 1 );
    }
    if( ( f = fopen( argv[1], "wb+" ) ) == NULL )
    {
        printf( "failed to open '%s' for writing.\n", argv[0] );
        return( 1 );
    }
    entropy_init( &entropy );
    ret = ctr_drbg_init( &ctr_drbg, entropy_func, &entropy, (const unsigned char *) "RANDOM_GEN", 10 );//ctr_drbg_init第四个参数相当于feed,可以是任意字符串,第一参数数是熵值函数,即输入一串数据计算熵值
    if( ret != 0 )
    {
        printf( "failed in ctr_drbg_init: %d\n", ret );
        goto cleanup;
    }
    ctr_drbg_set_prediction_resistance( &ctr_drbg, CTR_DRBG_PR_OFF );
#if defined(POLARSSL_FS_IO)
    ret = ctr_drbg_update_seed_file( &ctr_drbg, "seedfile" );
    if( ret == POLARSSL_ERR_CTR_DRBG_FILE_IO_ERROR )
    {
        printf( "Failed to open seedfile. Generating one.\n" );
        ret = ctr_drbg_write_seed_file( &ctr_drbg, "seedfile" );
        if( ret != 0 )
        {
            printf( "failed in ctr_drbg_write_seed_file: %d\n", ret );
            goto cleanup;
        }
    }
    else if( ret != 0 )
    {
        printf( "failed in ctr_drbg_update_seed_file: %d\n", ret );
        goto cleanup;
    }
#endif
    for( i = 0, k = 768; i < k; i++ )
    {
        ret = ctr_drbg_random( &ctr_drbg, buf, sizeof( buf ) );
        if( ret != 0 )
        {
            printf("failed!\n");
            goto cleanup;
        }
        fwrite( buf, 1, sizeof( buf ), f );
        printf( "Generating 32Mb of data in file '%s'... %04.1f" \
                "%% done\r", argv[1], (100 * (float) (i + 1)) / k );
        fflush( stdout );
    }
    ret = 0;
cleanup:
    printf("\n");
    fclose( f );
    entropy_free( &entropy );
    return( ret );
}
一般建议使用CTR-DRBG作为主要的随机数发生器。。。。。。。。。。

补充术语:

1)熵(Entropy):在封闭系统中衡量无序、随机或差异性的量度,在信息论中,一个
离散随机变量的熵定义为:


其中的pi是各事件发生的概率。
2)熵源(Entropy Source):不可预测数据流的源。不一定满足均匀分布,熵源包括噪
声源,例如热噪声或者硬盘寻道时间,数字化过程,评估过程,选择性条件化过程和健康
度测试等等。
3)健康度测试(Health Testing):在运行中或者之前测试和验证算法实现工作情况是
否符合预期设计要求。
4)内部状态(Internal State):确定性随机数产生器初始化以后存储在其中的信息集合。
5)时间随机数(Nonce):一个基于时间变化的变量,几乎不可能重复,例如时间戳

6)个性化字符串(Personalization String):一个可选的字符串,混合了秘密输入和时
间随机数,用于产生随机数种子。
7)安全强度(Security Strength):一个与破解密码系统需要进行的操作数相关的数字。
在这个标准中,该数字为(112、128、192、256)集合中的一个,需要进行的操作数为
2Security_Strength。
8)种子(Seed):一个字符串用于确定性随机数产生器系统的输入,它决定了确定性
随机数产生器的部分内部状态,它的熵值必须足以满足系统安全强度的要求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值