測試步驟
- 1.准備測試數據
使用待測的(偽)隨機數發生器,產生足夠長度的隨機數序列。(樣本參數見附錄)
- 2.在NIST的測試源碼中,添加4個國密特有的測試用例
撲克測試,游程分布測試,二元推導測試,自相關測試
-
3.編譯源碼得到測試程序
在sts-2.1.2目錄下make即可
-
4.運行測試程序,選擇待測試數據,按照NIST測試用例和測試參數進行設置
1.執行測試程序,$ ./assess 1000000
2. 輸入0,選擇從文件讀入隨機數
3. 輸入隨機數路徑及文件名,例如data/data1.bin
4. 輸入0,選擇NIST測試模式
5. 輸入2,選擇測試所有NIST用例
6. 輸入0,NIST用例使用默認參數即可(如果需要修改參數輸入相應的編號進行修改)
7. 輸入1000,選擇測試的樣本數量
8. 輸入1,選擇輸入的文件類型為二進制(選擇0表示全是01的ASCII文件)
9. 按回車即開始測試
-
5.測試結束之后,分析測試結果,看是否滿足預期要求
-
6.運行測試程序,選擇待測試數據,按照國密規范選擇對應測試用例,並進行參數設置
1.執行測試程序 $ ./assess 1000000
2. 輸入0,選擇從文件讀入隨機數
3. 輸入隨機數路徑及文件名,例如data/data1.bin
4. 輸入1,選擇國密測試模式,固定為國密的測試參數
5. 輸入3,選擇測試所有GM用例
6. 輸入1000,選擇測試的樣本數量
7. 輸入1,選擇輸入的文件類型為二進制(選擇0表示全是01的ASCII文件)
8. 按回車即開始測試
- 7.測試結果之后,分析測試結果,看是否滿足預期要求
結果分析
- 1.通過測試的樣本比例(NIST標准)
根據樣本總個數和顯著性水平,計算判定用例通過的最小樣本個數
對於樣本數為1000,顯著性水平為0.01的情況,通過的比例需要在0.98以上
即1000的樣本需要有980個通過。
- 2.P值均勻分布(僅NIST)
對每個測試樣本的P值結果,按照0.1的區間間隔進行數量統計,計算P值統計結果的P值。
如果最終的P值大於0.0001,則認為是均勻分布的。
序號 | 檢測項目 | 國密參數 | NIST參數 |
---|---|---|---|
1 | 塊內頻數測試 | m=100 | m=128 |
2 | 撲克測試(國密) | m=4; m=8 | / |
3 | 重疊子序列測試 | m=2; m=5 | m=16 |
4 | 塊內最長游程測試 | m=10000 | m=10000 |
5 | 二元推導測試(國密) | k=3; k=7 | / |
6 | 自相關測試(國密) | d=1, 2, 8, 16 | / |
7 | 矩陣秩測試 | M=Q=32 | M=Q=32 |
8 | 近似熵測試 | m=2; m=5 | m=10 |
9 | 線性復雜度測試 | m=500 | m=500 |
10 | 非重疊模板測試(NIST) | / | m=9 |
11 | 重疊模板測試(NIST) | / | m=9 |
12 | 通用測試 | L=7,Q=1280 | L=7,Q=1280 |
顯著性水平α=0.01
樣本參數
參數 | 值 |
---|---|
樣本長度 | 10^6 bits |
樣本個數 | 1000 |
隨機數樣本生成方法
- 1.openssl隨機數樣本生成方法
openssl rand -out data.openssl 1000000000
- 2.用C語言中rand函數生成隨機數樣本(glibc版本2.27)
./c_rand 1024 data.c_rand 1000000000
- 3.其中c_rand程序的源碼c_rand.c如下
#include <stdlib.h>
#include <stdio.h>
#define buffer 1024
int main(int argc, char *argv[])
{
int j, r, nbytes;
unsigned int seed;
FILE* fp = NULL;
size_t res = 0;
if (argc != 4) {
fprintf(stderr, "Usage: %s <seed> <rand_file> <nbytes>\n", argv[0]);
return -1;
}
seed = atoi(argv[1]);
nbytes = atoi(argv[3]);
srand(seed);
unsigned char* out = new unsigned char[buffer];
unsigned char* cur = out;
if (!(fp = fopen(argv[2], "wb")))
{
printf("file %s open fail!", argv[2]);
delete[] out;
return -1;
}
for (j=0;j<nbytes; ++j) {
r = rand()%256;
*cur++ = *((unsigned char*)(&r));
if((!(( j + 1 ) % buffer)) || ( j + 1 == nbytes))
{
size_t num = j % buffer + 1;
res = fwrite(out, 1, num, fp);
if (res != num)
{
fclose(fp);
delete[] out;
printf("file %s write fail!", argv[2]);
return -1;
}
cur = out;
}
}
fclose(fp);
delete[] out;
return 0;
}
- 4.采集握手中ClientHello隨機數
生成隨機數命令:
openssl s_server -engine ./engine.so -cert test/rsa-ext.pem -key test/rsa.key -CAfile ca/rsa-ca.pem -www -accept 8888
./ssl -h 192.168.1.10 -p 8888 -s 128000000 -f binary -o data.handshake -m tls1_2
- 5.采集硬件加密卡生成的隨機數樣本
前置條件:完成硬件安裝,驅動安裝,編譯openssl 引擎得到engine.so
openssl rand -engine ./engine.so -out data.cryptocard 1000000000
實驗結果
總結
本來打算自己嘗試編碼或者實在不行找一下代碼嘗試自己修改,最終發現自己暫時還是沒那個能力,所以還是使用了NIST的測試源碼,在網上查閱博客跟着博客運行了起來。感性認識了一下偽隨機數的檢測。后面打算找一些論文自己看看,嘗試寫一篇綜述類文章發表。以上就是最近的學習總結,如有不足請老師指正。