Windows系统真随机数生成器实现

Windows BCryptGenRandom 真随机数生成器

基于Windows Cryptography API: Next Generation (CNG)

Windows CNG API

_bcrypt = ctypes.WinDLL("bcrypt")
BCryptGenRandom = _bcrypt.BCryptGenRandom
BCryptGenRandom.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_ulong]
BCryptGenRandom.restype = ctypes.c_ulong
  • 直接调用Windows底层的bcrypt.dll
  • 明确定义C函数参数和返回类型
  • 检查API调用状态码

基础字节生成 (_gen_bytes)

def _gen_bytes(self, n: int) -> bytes:
    if n <= 0:
        return b""
    buf = ctypes.create_string_buffer(n)
    status = BCryptGenRandom(None, buf, ctypes.c_ulong(n), 
                            ctypes.c_ulong(BCRYPT_USE_SYSTEM_PREFERRED_RNG))
    if status != 0:
        raise OSError(f"BCryptGenRandom failed with status 0x{status:08X}")
    return buf.raw
  • BCRYPT_USE_SYSTEM_PREFERRED_RNG系统选择最佳熵源
  • 零拷贝返回
  • 将非零状态码视为错误

2.2 精确比特控制 (random_bits_bytes)

def random_bits_bytes(self, n_bits: int) -> bytes:
    if n_bits <= 0:
        return b""
    n_bytes = (n_bits + 7) // 8  # 向上取整计算字节数
    data = self._gen_bytes(n_bytes)
    excess_bits = n_bytes * 8 - n_bits
    if excess_bits:
        as_int = int.from_bytes(data, "big")
        as_int &= (1 << (n_bytes * 8 - excess_bits)) - 1  # 掩码清除
        data = as_int.to_bytes(n_bytes, "big")
    return data

比特字符串生成 (random_bits_str)

def random_bits_str(self, n_bits: int) -> str:
    b = self.random_bits_bytes(n_bits)
    bitstr = bin(int.from_bytes(b, "big"))[2:].rjust(len(b) * 8, "0")
    return bitstr[:n_bits]
  1. 获取精确比特数的字节数据
  2. 转换为二进制字符串表示
  3. 填充前导零确保完整字节表示
  4. 截取精确的比特数

均匀分布整数生成 (randint)

def randint(self, a: int, b: int) -> int:
    if a > b:
        raise ValueError("")
    width = b - a + 1
    if width == 1:
        return a
    bits = width.bit_length()
    bytes_needed = (bits + 7) // 8
    while True:
        rnd = int.from_bytes(self._gen_bytes(bytes_needed), "big")
        rnd &= (1 << bits) - 1  # 掩码到精确比特数
        if rnd < width:
            return a + rnd

拒绝采样算法:

  • 范围计算:width = b - a + 1 确定可能值的数量
  • 比特优化:仅生成必要的随机比特
  • 无偏保证:拒绝超出范围的值,确保均匀分布

熵源质量

Windows CNG提供的熵源包括:
硬件 RNG (Intel RDRAND/RDSEED)直接来自硬件的物理过程。
系统中断时序: 鼠标移动、键盘敲击、磁盘读写等硬件中断发生的时间点
硬件性能计数器 (HPC): CPU 周期、指令计数器等
用户输入事件: 鼠标的移动轨迹、按键的时间间隔等
网络数据包时序: 网络数据包到达网卡的时间差

调用

rng = TrueRNG()
encryption_key = rng.random_bytes(32)  # 256位AES密钥
# 随机密码盐
salt = rng.random_bytes(16)
# 会话ID
session_id = rng.random_bits_str(128)
# 随机端口号
port = rng.randint(1024, 65535)
# 随机选择
options = ['A', 'B', 'C', 'D']
random_choice = options[rng.randint(0, len(options)-1)]
posted @ 2025-11-06 11:05  lumiere_cloud  阅读(42)  评论(0)    收藏  举报