65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.67/5 (4投票s)

2018年3月5日

CPOL

2分钟阅读

viewsIcon

14443

downloadIcon

238

本文介绍如何使用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 201file_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()

Greyscale image of generated data

结论

从TPM生成随机数并测试后,发现它是一个相当不错的生成器...

Windows10笔记本电脑中的TPM随机生成器有多随机? - CodeProject - 代码之家
© . All rights reserved.