6

/dev/random 出力を openssl のキー生成のシードとして使用するつもりだったので、何をしようとしているのかを確認するためだけに、この小さなプログラムを書きました。

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

#define LEN 128

void uc2hex(char* hex, unsigned char* uc, unsigned short uc_len)
{
    FILE* bp=fmemopen(hex,2*uc_len+1,"w");
    unsigned short i;
    for(i=0;i<uc_len;i++)
    {
        fprintf(bp,"%02x",uc[i]);
        //printf("%02x\n",uc[i]);
        //fprintf(bp,"%d-",i);
    }
    fprintf(bp,"%c",'\0');
    fclose(bp);
}

int main()
{
    unsigned char buf[LEN];
    char str[2*LEN+1];
    int fd=open("/dev/random",O_RDONLY);
    read(fd,buf,LEN);
    uc2hex(str,buf,LEN);
    printf("%s\n",str);
    close(fd);
    return 0;
}

プログラムを 1 ~ 2 回実行したところ、すべて正常に動作しているように見えましたが、短いシーケンスで再度 4 回実行したところ、次のような結果が得られました。

[walter@eM350 ~]$ ./random 
0ee08c942ddf901af1278ba8f335b5df8db7cf18e5de2a67ac200f320a7a20e84866f533667a7e66a4572b3bf83d458e6f71f325783f2e3f921868328051f8f296800352cabeaf00000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000
[walter@eM350 ~]$ ./random 
1f69a0b931c16f796bbb1345b3f58f17f74e3df600000000bb03400000000000ffffffff00000000880e648aff7f0000a88103b4d67f000000305cb4d67f000030415fb4d67f0000000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000
[walter@eM350 ~]$ ./random 
4e8a1715238644a840eb66d9ff7f00002e4e3df600000000bb03400000000000ffffffff00000000a8ec66d9ff7f0000a871a37ad97f00000020fc7ad97f00003031ff7ad97f0000000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000
[walter@eM350 ~]$ ./random 
598c57563e8951e6f0173f0cff7f00002e4e3df600000000bb03400000000000ffffffff0000000058193f0cff7f0000a8e1cbda257f0000009024db257f000030a127db257f0000000000000000000001000000000000005d08400000000000c080300e00000000000000000000000010084000000000000006400000000000

ほとんど同じなので、これらは 128 バイトのランダム文字列以外のすべてのように思えます。次に、NSA が Linux カーネルの乱数ジェネレーターを改ざんした可能性を除いて、これは私のマシンで利用可能なエントロピーと関係があると推測することしかできませんでした。私の質問は次のとおりです。1) この推測は正しいですか? 2) 1) が正しいと仮定すると、実際のランダムなバイト シーケンスを生成するのに十分なエントロピーがあるかどうかをどのように知ることができますか?

4

2 に答える 2

2

他の人が示唆しているように、読み取ったバイト数の戻り値を確認する必要があります。

/dev/random に利用可能な十分なバイトがない場合、返されるバイト数は少なくなります。

ただし、次の呼び出しでは引き続き予想される長さを使用します。

uc2hex(str,buf,LEN);
printf("%s\n",str);

したがって、初期化されていないメモリを変換して印刷しています。後続の呼び出しで同じ値が表示されることに驚きはありません。そのメモリが呼び出し間で書き込まれていない場合、値は変更されないためです。

編集:より良いでしょう:

int nBytes=read(fd,buf,LEN);
uc2hex(str,buf,nBytes);
printf("%s\n",str);
于 2013-10-09T09:00:21.330 に答える