Windows 10 笔记本电脑中 TPM 随机生成器的随机性如何?






2.67/5 (4投票s)
本文介绍如何使用Windows 10中的可信平台模块(TPM)生成随机数据,并使用dieharder测试套件测试其随机性。
引言
如今,大多数系统服务器、笔记本电脑和手机都包含TPM(可信平台模块)。这些硬件模块可用于存储和生成加密密钥。除此之外,还有一个硬件随机数生成器。该RNG主要使用热噪声/散粒噪声时钟抖动作为其熵源,并将其发送到单向哈希函数以保证随机性。本文详细介绍了使用TPM模块生成随机数据并使用标准测试套件Dieharder进行测试。 即使Dieharder测试套件并非旨在测试二进制文件,但这仍然是最好的选择。 请查看本文,以了解有关TPM的更多信息...
您可以在这里了解有关Dieharder随机数生成器测试套件的更多信息...
在获取随机数之前需要检查的事项...
在您的Windows 10机器上,检查TPM是否已启用并正常工作,可以通过运行TPM.msc来完成。
在Windows中从TPM生成随机数据的代码...
以下小片段用于生成包含来自TPM模块的随机数据的的文件。 它使用下一代密码学(CNG)函数来访问TPM随机数生成器。 如果有人想使用它,则添加了VS项目...
#include<fstream>
#include<iostream>
#include<Windows.h>
#include<bcrypt.h>
#include<string>
#define BLOCK_SIZE 1024
#define ONE_MB 1024 * 1024
using namespace std;
// Usage1: tpm_randomgen <size of file in MB>
// Usage2: tpm_randomgen <filename> <size of file in MB>
// Ex tpm_randomgen randbinary 1024
int main(int argc, char *argv[]) {
UCHAR buf[BLOCK_SIZE];
BCRYPT_ALG_HANDLE pHandle = NULL;
long filesize = 1; // default 1 MB unit size
string filename = "randgen";
if (argc == 3) {
filename = string(argv[1]);
filesize = stol(string(argv[2]));
} else if (argc == 2) {
filesize = stol(string(argv[1]));
}
filesize = (filesize * ONE_MB) / _countof(buf); // this will convert into MB
ofstream outfile(filename.c_str(), std::ios::binary);
// MS_PLATFORM_CRYPTO_PROVIDER will make sure random data is fetched from TPM
// if TPM not installed it defaults to windows default provided
if (0 == BCryptOpenAlgorithmProvider(
&pHandle,
BCRYPT_RNG_ALGORITHM,
MS_PLATFORM_CRYPTO_PROVIDER,
NULL)) {
for (long i = 0; i < filesize; i++) {
BCryptGenRandom(pHandle, buf, sizeof(buf), NULL);
outfile.write((char *)&buf[0], _countof(buf));
}
BCryptCloseAlgorithmProvider(pHandle, NULL);
}
return (0);
}
Dieharder测试套件需要大量数据才能正确运行测试。 如果数据不足,测试可能无法提供所需的结果。 运行上述代码约三个小时后,我可以在二进制文件中生成约2.6GB的随机数据。 然后将此文件复制到一台Linux机器上,在那里Dieharder更方便运行。
使用二进制文件生成二进制格式的随机数据...
TPM_randomgen
<文件大小,单位为MB>
示例
TPM_randomgen 1024
将生成默认二进制文件“randgen”,其中包含1GB的数据。
TPM_randomgen
<文件名> <文件大小,单位为MB>
示例
TPM_randomgen randomdata.bin 5120
上述运行将创建一个randomdata.bin文件,其中包含从TPM获取的5GB随机数据,5120是文件大小,单位为MB。
生成随机数据后,是时候测试结果了...
dieharder -g 201 -f randgen -a > report.txt
-g 201
将file_input_raw
指定给测试套件。
测试结果...
附带的report.zip文件中记录了全面的测试结果。 总体上,90个测试通过,11个测试失败,10个测试结果不确定。 即使有几个测试失败并且有几个测试结果不确定,也可以给予TPM RNG生成器足够的信任。
从随机数据创建灰度图像...
人眼可以很容易地检测到图像中的任何模式。 因此,为了检查生成的数据是否真正随机,另一个检查是使用随机数据创建图像并检查是否存在任何模式...
一个小型的Python片段可以完成此操作...
import matplotlib.pyplot as plt
import numpy as np
randfile = open("randgen", "r")
arr = np.fromfile(randfile, dtype=np.uint16)
#To derive n of n * n matrix
dim = int((arr.size)**(1/2.0))
#To make it exact n * n matrix
arr = arr[:(dim * dim)]
arr = arr.reshape(dim, dim)
plt.imshow(arr, cmap="gray")
plt.show()
结论
从TPM生成随机数并测试后,发现它是一个相当不错的生成器...