随机数发生器设计(二)

news2024/11/26 2:44:23

一、软件随机数发生器组成概述

密码产品应至少包含一个随机比特生成器。
软件随机数发生器应遵循GM/T 0105-2021《软件随机数发生器设计指南》要求,使用SM3或SM4算法作为生成随机比特算法。

本文以SM3算法为例描述软件随机数发生器的一个设计实例。需要注意的是,本实例仅为参考,实际熵源信息、熵估计方法和算法等都可根据需要变动。

软件随机数发生器采集当前运行环境的传感器信息作为熵源,包括当前时间、CPU信息、RAM信息、磁盘信息、网络信息。以上熵源信息经健康测试和熵评估后,作为熵数据输入到熵池。熵数据填满熵池后,可以经扩展函数处理后输入DRNG。扩展函数处理后的熵数据可以反馈到熵池。

DRNG根据熵输入数据和内部状态生成输出随机数,并维护自身种子信息和正确性。初始化函数获取扩展函数的输出和外部输入的nonce更新内部状态。当重播种计数器或时间间隔达到阈值时,产品会执行重播种函数更新内部状态。输出函数可以按照接口要求输出指定长度的随机数。DRNG实现已知答案自测试,在产品上电初始化或有自测试需求时执行。
软件随机数发生器框架

二、熵源

软件随机数发生器采用系统信息作为熵源,包括当前时间、CPU信息、RAM信息、磁盘信息、网络信息。熵源信息如下表所示。
熵源信息
在熵池存在空闲空间时,产品获取熵源信息,经连续健康测试后写入熵池。每次采集的熵源信息RAW_ENTROPY =时间信息|| CPU信息||RAM信息||磁盘信息||网络信息,熵值约29.84比特。熵池为512字节大小。

当前时间信息随时间自然增长,精确到纳秒,外界很难预测产品获取当前时间的精确时间节点,从而无法预测产品得到的该熵源信息,因此在某一时间节点,时间信息相当于独占熵源;CPU信息、RAM信息、磁盘信息和网络信息都在系统运行过程中随系统业务环境动态变化。例如,外界几乎无法预测CPU中断的到来时间和执行时间。因此,CPU信息、RAM信息、磁盘信息和网络信息在某一时间节点相当于独占熵源。

本软件随机数发生器未采用硬件随机数发生器和系统随机数发生器。

采集熵源信息的代码如下。


#generate raw entropy from system source - time
#return 4 bytes
def RNG_Generate_Raw_Entropy_Source1():
    return (int(time_ns()) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)

#generate raw entropy from system source - cpu
# return 16 bytes
def RNG_Generate_Raw_Entropy_Source2():
    usercputime = (int(psutil.cpu_times().user*1000000) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)
    idlecputime = (int(psutil.cpu_times().idle*1000000) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)
    interruptcputime = (int(psutil.cpu_times().interrupt*1000000) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)
    dpccputime = (int(psutil.cpu_times().dpc*1000000) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)
    return usercputime + idlecputime + interruptcputime + dpccputime
#generate raw entropy from system source - ram
# return 8 bytes
def RNG_Generate_Raw_Entropy_Source3():
    usedvmmem = (int(psutil.virtual_memory().used) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)
    usedswapmem = (int(psutil.swap_memory().used) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)
    
    return usedvmmem + usedswapmem
#generate raw entropy from system source - disk
# return 8 bytes
def RNG_Generate_Raw_Entropy_Source4():
    read_bytes = (int(psutil.disk_io_counters().read_bytes) & 0xFFFF).to_bytes(2, byteorder = 'big', signed=False)
    write_bytes = (int(psutil.disk_io_counters().write_bytes) & 0xFFFF).to_bytes(2, byteorder = 'big', signed=False)
    read_time = (int(psutil.disk_io_counters().read_time) & 0xFFFF).to_bytes(2, byteorder = 'big', signed=False)
    write_time = (int(psutil.disk_io_counters().write_time) & 0xFFFF).to_bytes(2, byteorder = 'big', signed=False)
    return read_bytes + write_bytes + read_time + write_time
#generate raw entropy from system source - network
# return 8 bytes
def RNG_Generate_Raw_Entropy_Source5():
    # print(psutil.net_io_counters())
    bytes_sent = (int(psutil.net_io_counters().bytes_sent) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)
    bytes_recv = (int(psutil.net_io_counters().bytes_recv) & 0xFFFFFFFF).to_bytes(4, byteorder = 'big', signed=False)
    return bytes_sent + bytes_recv

三、熵池

随机数数发生器的熵池大小为512字节。在当前熵估计情况下,512字节大小的熵池具备的熵值可满足大于256比特的要求。
熵池采用SM3_df函数作为扩展函数,流程图如下。
SM3_df
1) 根据输入的返回数据长度(实际为440比特)和输出数据长度256比特计算循环次数。计算循环次数时使用向上取整方式。
2) 对计数器赋初值1,对临时数据赋初值空。
3) 计算SM3(计数器值||返回数据长度||输入熵源数据)。
4) 临时数据更新为临时数据||SM3结果。
5) 计数器增1。
6) 判断循环是否结果,若结束则跳转至第7步,否则跳转至第3步。
7) 取临时数据左侧指定长度数据,返回

8def sm3Hash(hashbytes:bytes):
9)	    temp = sm3_hash([i for i in hashbytes])
10return bytes.fromhex(temp)
1112def SM3_df(input_string, no_of_bits_to_return):
13)	    temp = bytes([])
14len = math.ceil(no_of_bits_to_return/outlen)
15)	    counter = 0x01
16for i in range(len):
17)	        temp = temp + sm3Hash(bytes([counter]) + no_of_bits_to_return.to_bytes(4, 'big') + input_string)
18)	        counter = counter + 1
19return temp[0:int(no_of_bits_to_return/8)]

熵池更新是采用GM/T 0105 附录A所示方式。
熵池
1) 以熵池中第一个字(4字节)为当前字,开始执行遍历。
2) 临时数据temp更新为输入字与当前字异或结果。
3) 临时数据temp依次与某偏移字异或,异或结果更新至临时数据。偏移值分别设定为1、25、51、76、103。
4) 临时数据取低3位作为索引,获取预置表值。。
5) 临时数据右移3位与步骤4预置表值异或。
6) 更新当前值为步骤5结果。
7) 判断是否遍历熵池,若未完成,回到步骤2;否则结束熵池更新。

9#init entropy pool
10def RNG_Init_POOL():
11global entropy_pool
12)	    entropy_pool = []
13for i in range(128):
14)	        entropy_pool.append(bytes([0,0,0,0]))
15#four bytes xor function
16def RNG_Word_XOR(a:bytes, b:bytes):
17return bytes([a[i] ^ b[i] for i in range(4)])
18#word shift function
19def RNG_Word_Shift_Right(a:bytes, len:int):
20return bytes([a[i] >> len for i in range(4)])
21)	table = [0x0, 0x3b6e20c8, 0x76dc4190, 0x4db26158, 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278]
22#add 1 word entropy to entropy pool 
23def RNG_Add_Entropy(entropyWord:bytes):
24global entropy_pool
25global table
26if len(entropy_pool) != 128:
27)	        RNG_Init_POOL()
28for i in range(128):
29)	        temp = RNG_Word_XOR(entropyWord, entropy_pool[i])
30)	        temp = RNG_Word_XOR(temp, entropy_pool[(i+1)%128])
31)	        temp = RNG_Word_XOR(temp, entropy_pool[(i+25)%128])
32)	        temp = RNG_Word_XOR(temp, entropy_pool[(i+51)%128])
33)	        temp = RNG_Word_XOR(temp, entropy_pool[(i+76)%128])
34)	        temp = RNG_Word_XOR(temp, entropy_pool[(i+103)%128])
35)	        temp = RNG_Word_XOR(RNG_Word_Shift_Right(temp, 3), table[temp[3] & 7].to_bytes(4, 'big'))
36)	        entropy_pool[i] = temp 

如果商用密码产品认证中遇到问题,欢迎加微信symmrz或13720098215沟通。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/578527.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在华为OD机试中获得满分?Java实现【猜字谜】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1、题目描述2、输入描述3、输出描述…

python爬虫——pandas的简单使用

pandas作为爬虫中最重要的包之一,我们要想学好爬虫,就必须要深入了解pandas 直接上代码 import pandas as pd import numpy as npdata pd.DataFrame(np.arange(16).reshape((4,4)),index[a,b,c,d],#如果不写列索引默认为0,1,…

基于html+css的图展示96

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

【源码解析】Nacos配置热更新的实现原理

使用入门 使用RefreshScopeValue,实现动态刷新 RestController RefreshScope public class TestController {Value("${cls.name}")private String clsName;}使用ConfigurationProperties,通过Autowired注入使用 Data ConfigurationProperti…

警惕AI换脸技术:近期诈骗事件揭示的惊人真相

大家好,我是可夫小子,《小白玩转ChatGPT》专栏作者,关注AIGC、读书和自媒体。 目录 1. deepswap 2. faceswap 3. swapface 总结 📣通知 近日,包头警方公布了一起用AI进行电信诈骗的案件,其中福州科技公…

医院PACS系统:三维多平面重建操作使用

三维多平面重建(MPR\CPR)界面工具栏: 按钮1:点击此按钮,用鼠标拖动正交的MPR定位线,可以动态浏览MPR图像。 按钮2:点击此按钮,按下鼠标左键在图像上作任意勾边,弹起鼠标…

python3.8安装rpy2

python3.8安装rpy2 rpy2是一个可以让r和python交互的库,非常强大,但是安装过程有些坎坷。 安装r语言 安装时首先需要安装r语言。 官网下载链接:https://www.r-project.org/ 选择与自己电脑相应的版本就好。 安装rpy2 然后需要安装rpy2库…

Radxa ROCK 5A RK3588S 开箱 vs 树莓派

Rock5 Model A 是一款高性能的单板计算机,采用了 RK3588S (8nm LP 制程)处理器,具有 4 个高达 2.4GHz 的 ARM Cortex-A76 CPU 核心、4 个高达 1.8GHz 的 Cortex-A55 内核和 Mali-G610 MP4 GPU,支持 8K 60fps 视频播放&#xff0c…

光力转债上市价格预测

光力转债 基本信息 转债名称:光力转债,评级:A,发行规模:4.0亿元。 正股名称:光力科技,今日收盘价:22.53元,转股价格:21.46元。 当前转股价值 转债面值 / 转股…

Redis的常用数据结构之字符串类型

redis中的数据结构是根据value的值来进行区别的,主要分了String、Hash、List、Set(无序集合)、Zset(有序集合) 字符串(String) String类型是redis中最基础的数据结构,也可以理解为…

Java基础面试题突击系列6

👩🏻 作者:一只IT攻城狮 ,关注我不迷路 ❤️《java面试核心知识》突击系列,持续更新… 💐 面试必知必会学习路线:Java技术栈面试系列SpringCloud项目实战学习路线 📝再小的收获x365天…

一、CNNs网络架构-基础网络架构(LeNet、AlexNet、ZFNet)

目录 1.LeNet 2.AlexNet 2.1 激活函数:ReLU 2.2 随机失活:Droupout 2.3 数据扩充:Data augmentation 2.4 局部响应归一化:LRN 2.5 多GPU训练 2.6 论文 3.ZFNet 3.1 网络架构 3.2 反卷积 3.3 卷积可视化 3.4 ZFNet改…

Integer源码

介绍 Integer是int类型的包装类,继承自Number抽象类,实现了Comparable接口。提供了一些处理int类型的方法,比如int到String类型的转换方法或String类型到int类型的转换方法,当然也包含与其他类型之间的转换方法。 Comparable提供…

3ds MAX 基本体建模,长方体、圆柱体和球体

3ds MAX基本页面如下: 生成新的几何体在右侧: 选择生成的对象类型即可,以下为例子: 1、长方体建模 选择建立的对象类型为长方形 在 任意一个窗口绘制,鼠标滑动 这里选择左上角的俯视图 松开鼠标后,可以…

单片机GD32F303RCT6 (Macos环境)开发 (二十九)—— GD32通过蓝牙透传模块 IAP升级

GD32通过蓝牙透传模块 IAP升级 1、思路 上一节手机App可以通过HC-08模块控制mcu的开锁,关锁的动作,那么我们是不是可以将mcu的升级文件通过hc-08模块发送给gd32,完成gd32程序的自升级呢? 2、命令协议 蓝牙透传模块每次只能发2…

Selenium的使用

一、基础 1、特点 selenium 是web中基于UI的自动化测试工具,它支持多平台、多语言、多浏览器,还有丰富的API。 2、原理 自动化脚本代码会创建一个http请求发送给浏览器驱动进行解析,浏览器驱动会操控浏览器执行测试,浏览器接着…

AirServer电脑通用版下载及使用教程

AirServer 是一款功能十分强大的投屏软件,支持并适用于 Windows和Mac。AirServer 是接收方,而不是发送方。 AirServer 只允许您接收镜像或流媒体内容,反之则不行。AirServer虽然功能十分强大,但是整体操作和使用都十分简单&#x…

如何在华为OD机试中获得满分?Java实现【知识图谱新词挖掘1】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述…

【STL】list的模拟实现

目录 前言 结构解析 默认成员函数 构造函数 拷贝构造 赋值重载 析构函数 迭代器 const迭代器 数据修改 insert erase 尾插尾删头插头删 容量查询 源码 前言 🍉list之所以摆脱了单链表尾插麻烦,只能单向访问等缺点,正是因为其…

日常 - HttpURLConnection 网络请求 TLS 1.2

文章目录 环境前言HTTPS 请求流程服务端支持JDK 验证资源 环境 JDK 8 Hutool 4.5.1 前言 应供应商 DD 的 TLS 版本升级通知,企业版接口升级后 TLS 1.0 及 1.1 版本请求将无法连接,仅支持 TLS 1.2 及以上版本的客户端发起请求。 当前项目使用 Hutool …