openssl使用哈希算法生成随机密钥
文章目录
- 一、openssl中随机数函数
- **OpenSSL 随机数函数概览**
- 1. **核心随机数函数**
- **常用函数详解**
- 1. `RAND_bytes`
- 2. `RAND_priv_bytes`
- 3. `RAND_seed` 和 `RAND_add`
- 4. `RAND_status`
- **随机数生成器的熵池**
- **常见用例**
- **注意事项**
- 二、使用哈希算法生成随机的密钥
一、openssl中随机数函数
OpenSSL 提供了一套功能强大的随机数生成函数,用于生成高质量的伪随机数。随机数在密码学中至关重要,广泛用于密钥生成、盐值生成、初始化向量 (IV) 等安全操作。
OpenSSL 随机数函数概览
1. 核心随机数函数
| 函数名称 | 描述 |
|---|---|
RAND_bytes | 生成高质量的伪随机字节。 |
RAND_priv_bytes | 生成高质量伪随机字节,推荐用于对安全性要求更高的密钥生成。 |
RAND_pseudo_bytes | 生成伪随机字节(不保证是加密级别安全,已被弃用)。 |
RAND_seed | 手动为伪随机数生成器添加种子值。 |
RAND_add | 添加额外的熵(种子数据)到伪随机数生成器的池中。 |
RAND_status | 检查随机数生成器是否被正确初始化。 |
RAND_poll | 自动收集熵以初始化随机数生成器(由内部调用)。 |
常用函数详解
1. RAND_bytes
-
作用:生成高质量的加密级别伪随机字节。
-
函数原型:
int RAND_bytes(unsigned char *buf, int num);buf:指向用于存储随机字节的缓冲区。num:要生成的随机字节数。- 返回值:
- 成功返回
1。 - 如果随机数生成器未正确初始化,返回
0。
- 成功返回
-
示例:
unsigned char random_bytes[16]; if (RAND_bytes(random_bytes, sizeof(random_bytes)) == 1) {printf("生成的随机数:");for (int i = 0; i < sizeof(random_bytes); i++) {printf("%02x", random_bytes[i]);}printf("\n"); } else {fprintf(stderr, "随机数生成失败!\n"); }
2. RAND_priv_bytes
- 作用:与
RAND_bytes类似,但专为高安全性应用设计(如密钥生成)。可能在实现中增加额外的保护。 - 函数原型:
int RAND_priv_bytes(unsigned char *buf, int num); - 使用方法与
RAND_bytes一致。
3. RAND_seed 和 RAND_add
-
作用:为随机数生成器添加种子值或熵,增强其随机性。
OpenSSL 的随机数生成器依赖熵池,通常会自动初始化,但可以通过这些函数手动添加种子数据。 -
函数原型:
void RAND_seed(const void *buf, int num); void RAND_add(const void *buf, int num, double entropy);buf:种子数据。num:种子数据的字节数。entropy:种子中估计的熵(单位是比特,范围 0 到 8*num)。
-
示例:
unsigned char seed_data[] = {0x12, 0x34, 0x56, 0x78}; RAND_seed(seed_data, sizeof(seed_data));
4. RAND_status
-
作用:检查随机数生成器是否被正确初始化。
-
函数原型:
int RAND_status(void);- 返回值:
- 如果熵池已初始化且可用随机性足够,返回
1。 - 否则返回
0。
- 如果熵池已初始化且可用随机性足够,返回
- 返回值:
-
示例:
if (RAND_status() == 1) {printf("随机数生成器已初始化!\n"); } else {printf("随机数生成器未初始化!\n"); }
随机数生成器的熵池
OpenSSL 的随机数生成器使用熵池作为随机性的来源,依赖于系统提供的随机性(如 /dev/random 或 /dev/urandom)。在大多数情况下,OpenSSL 会自动处理熵池的初始化,但开发者可以通过 RAND_seed 或 RAND_add 提供额外的种子数据。
常见用例
-
生成随机密钥:
unsigned char key[32]; // 256 位密钥 if (RAND_bytes(key, sizeof(key)) == 1) {printf("密钥生成成功!\n"); } -
生成随机初始化向量 (IV):
unsigned char iv[16]; // 128 位 IV if (RAND_bytes(iv, sizeof(iv)) == 1) {printf("IV 生成成功!\n"); } -
增强随机数生成器熵:
unsigned char extra_entropy[] = {0xde, 0xad, 0xbe, 0xef}; RAND_add(extra_entropy, sizeof(extra_entropy), 4.0); // 添加 4 比特熵
注意事项
-
使用
RAND_bytes或RAND_priv_bytes- 推荐使用这两个函数生成随机数,因为它们提供加密级别的安全性。
- 不建议使用
RAND_pseudo_bytes,因为它已被弃用。
-
熵的重要性
- 高质量的熵是随机数生成的核心。如果熵不足,生成的随机数可能会被预测,降低安全性。
-
平台依赖
- OpenSSL 的随机数生成器在不同平台上依赖系统的熵源,例如
/dev/urandom或 Windows 的 CryptGenRandom。
- OpenSSL 的随机数生成器在不同平台上依赖系统的熵源,例如
OpenSSL 的随机数生成函数设计灵活,满足了从简单随机需求到高安全性应用的各种场景。如果需要更高安全性的随机数生成,推荐使用 RAND_priv_bytes。
二、使用哈希算法生成随机的密钥
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/rand.h>
#include <openssl/evp.h>#define SEED_LENGTH 32 // 随机种子长度(32 字节 = 256 位)
#define KEY_LENGTH 32 // 密钥长度(32 字节 = 256 位)// 使用随机种子和哈希算法生成密钥
void generate_hashed_key(unsigned char *key, size_t key_length) {unsigned char seed[SEED_LENGTH]; // 随机种子// 生成随机种子if (!RAND_bytes(seed, sizeof(seed))) {fprintf(stderr, "随机种子生成失败!\n");exit(EXIT_FAILURE);}// 打印随机种子(调试用)printf("随机种子: ");for (size_t i = 0; i < sizeof(seed); i++) {printf("%02x", seed[i]);}printf("\n");// 使用 SHA-256 哈希函数对种子进行散列EVP_MD_CTX *mdctx = EVP_MD_CTX_new(); // 创建哈希上下文if (!mdctx) {fprintf(stderr, "创建哈希上下文失败!\n");exit(EXIT_FAILURE);}// 初始化哈希计算(使用 SHA-256)if (EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL) != 1) {fprintf(stderr, "哈希初始化失败!\n");EVP_MD_CTX_free(mdctx);exit(EXIT_FAILURE);}// 提供数据进行哈希计算if (EVP_DigestUpdate(mdctx, seed, sizeof(seed)) != 1) {fprintf(stderr, "哈希更新失败!\n");EVP_MD_CTX_free(mdctx);exit(EXIT_FAILURE);}// 获取哈希结果unsigned char hash[EVP_MAX_MD_SIZE];unsigned int hash_len;if (EVP_DigestFinal_ex(mdctx, hash, &hash_len) != 1) {fprintf(stderr, "哈希计算失败!\n");EVP_MD_CTX_free(mdctx);exit(EXIT_FAILURE);}// 释放哈希上下文EVP_MD_CTX_free(mdctx);// 取哈希结果的前 key_length 字节作为密钥if (key_length > hash_len) {fprintf(stderr, "密钥长度超出哈希值长度!\n");exit(EXIT_FAILURE);}memcpy(key, hash, key_length);// 打印生成的密钥(调试用)printf("生成的密钥: ");for (size_t i = 0; i < key_length; i++) {printf("%02x", key[i]);}printf("\n");
}int main() {unsigned char key[KEY_LENGTH]; // 存储生成的密钥// 调用密钥生成函数generate_hashed_key(key, KEY_LENGTH);return 0;
}
运行两次的结果:
这里可以看到每次运行后生成的密钥都是不一样的,这样就保证了密钥的不一致性。

相关文章:
openssl使用哈希算法生成随机密钥
文章目录 一、openssl中随机数函数**OpenSSL 随机数函数概览**1. **核心随机数函数** **常用函数详解**1. RAND_bytes2. RAND_priv_bytes3. RAND_seed 和 RAND_add4. RAND_status **随机数生成器的熵池****常见用例****注意事项** 二、使用哈希算法生成随机的密钥 一、openssl中…...
将word里自带公式编辑器编辑的公式转换成用mathtype编辑的格式
文章目录 将word里自带公式编辑器编辑的公式转换成用mathtype编辑的格式MathType安装问题MathType30天试用延期MathPage.wll文件找不到问题 将word里自带公式编辑器编辑的公式转换成用mathtype编辑的格式 word自带公式编辑器编辑的公式格式: MathType编辑的格式&a…...
校园失物招领系统基于 SpringBoot:点亮校园归还遗失物之光
2系统开发环境 2.1vue技术 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式JavaScript框架。 [5] 与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第…...
dhcpd服务器的配置与管理(超详细!!!)
前提条件: (1)虚拟机能够联网(如果nat模式不能联网的看另一期) CentOS7 NAT模式不能联网-CSDN博客 (2)系统是Centos8,因为下载的dhcp-server软件包版本和Centos7不匹配,如果你能成…...
Qml之基本控件
一.Qml常用控件 1.Text(显示普通文本和富文本) 1.1显示普通文本: Window { visible: true width: 320 height: 240 title: qsTr("Hello World") Text { text: "Hello World!" font.family: "Helvetica" font.pointSize: 24 color:…...
【Java从入门到放弃 之 Stream API】
Java Stream API Stream API行为参数化传递代码Lambda表达式Lambda 表达式的语法方法引用 Lambda 表达式的实际应用集合操作并发编程 Lambda 表达式的注意事项总结 Stream API Java8提供了一个全新的API - Stream。引入这个Stream的主要目的,一个是可以支持更好的并…...
Ruby On Rails 笔记1——Rails 入门
突然想跟着官方文档把Ruby On Rails过一遍,把一些有用的记下来就可以一直看了,do它! https://guides.rubyonrails.org/v7.2/ 注:官网是英文文档,我自己翻译了一下,不确保完全准确,只供自己学习开发使用。 …...
高效开发 Python Web 应用:FastAPI 数据验证与响应体设计
高效开发 Python Web 应用:FastAPI 数据验证与响应体设计 目录 🧑💻 FastAPI 的数据验证系统与 Pydantic 模型📦 响应体与模型:定义响应数据的最佳实践🔄 响应模型与查询参数的结合:增强灵活…...
基于“开源 2+1 链动 O2O 商城小程序”的门店拉新策略与流程设计
摘要:在数字化商业浪潮席卷之下,实体门店面临着激烈的市场竞争,如何高效拉新成为关乎门店生存与发展的关键问题。本文聚焦于“开源 21 链动 O2O 商城小程序”,深入探讨结合多种手段的门店拉新策略及详细流程设计。通过剖析到店扫码…...
33.5 remote实战项目之设计prometheus数据源的结构
本节重点介绍 : 项目要求 通过remote read读取prometheus中的数据通过remote write向prometheus中写入数据 准备工作 新建项目 prome_remote_read_write设计prometheus 数据源的结构初始化 项目要求 通过remote read读取prometheus中的数据通过remote write向prometheus中写…...
微服务springboot详细解析(一)
目录 1.Spring概述 2.什么是SpringBoot? 3.第一个SpringBoot程序 4.配置参数优先级 5.springboot自动装配原理 6.SpringBootApplication&SpringApplication.run 7.ConfigurationProperties(prefix "") 8.Validated数据校验 29、聊聊该如何写一…...
深入探讨Go语言中的双向链表
简介 双向链表是链表家族中的一种高级结构,每个节点不仅指向下一个节点,还指向上一个节点。今天,我们将学习如何在Go语言中实现和操作这种灵活的数据结构。 双向链表的优缺点 优点: 可以从任一方向遍历链表,灵活性高…...
Fastapi + vue3 自动化测试平台---移动端App自动化篇
概述 好久写文章了,专注于新框架,新UI界面的实践,废话不多说,开搞 技术架构 后端: Fastapi Airtest multiprocessing 前端: 基于 Vue3、Vite、TypeScript、Pinia、Pinia持久化插件、Unocss 和 Elemen…...
ElasticSearch easy-es 聚合函数 group by 混合写法求Top N 词云 分词
1.将用户访问记录表数据同步到ES,并且分词,获取用户访问最多前十条词语。 Elasticsearch、Easy-es 快速入门 SearchAfterPage分页 若依前后端分离 Ruoyi-Vue SpringBoot 使用结巴分词器 <!-- 分词器--><dependency><groupId>com.hua…...
在 ASP.NET C# Web API 中实现 Serilog 以增强请求和响应的日志记录
介绍 日志记录是任何 Web 应用程序的关键方面。它有助于调试、性能监控和了解用户交互。在 ASP.NET C# 中,集成 Serilog 作为记录请求和响应(包括传入和传出的数据)的中间件可以显著提高 Web API 的可观察性和故障排除能力。 在过去的几周里&…...
2024年顶级小型语言模型前15名
本文,我们将深入了解2024年备受瞩目的十五款小型语言模型(SLMs),它们分别是Llama 3.1 8B、Gemma2、Qwen 2、Mistral Nemo、Phi-3.5等。这些SLMs以其精巧的体积和高效率著称,它们不需要依赖庞大的服务器资源,…...
精通 Python 网络安全(一)
前言 最近,Python 开始受到越来越多的关注,最新的 Python 更新添加了许多可用于执行关键任务的包。我们的主要目标是帮助您利用 Python 包来检测和利用漏洞,并解决网络挑战。 本书将首先带您了解与网络和安全相关的 Python 脚本和库。然后&…...
【python自动化二】pytest集成allure生成测试报告
pytest本身不会直接生成测试报告,而allure是一种生成测试报告的公共插件,可与多种测试框架配合生成测试报告,本文介绍下如何集成allure生成测试报告。 1.allure安装 1.安装allure-pytest 先安装allure的pytest插件,用于在pytes…...
网络版本的通讯录青春版(protobuf)
环境搭建 Protobuf 还常⽤于通讯协议、服务端数据交换场景。 因为我们主要目的只是为了学习protobuf,因此对于客户端,原本应该具备: 新增⼀个联系⼈ ◦ 删除⼀个联系⼈ ◦ 查询通讯录列表 ◦ 查询⼀个联系⼈的详细信息 这样四个功能。 …...
开源模型应用落地-安全合规篇-用户输入价值观判断(三)
一、前言 在深度合规功能中,对用户输入内容的价值观判断具有重要意义。这一功能不仅仅是对信息合法性和合规性的简单审核,更是对信息背后隐含的伦理道德和社会责任的深刻洞察。通过对价值观的判断,系统能够识别可能引发不当影响或冲突的内容,从而为用户提供更安全、更和谐的…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...
解读《网络安全法》最新修订,把握网络安全新趋势
《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...
(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
AWS vs 阿里云:功能、服务与性能对比指南
在云计算领域,Amazon Web Services (AWS) 和阿里云 (Alibaba Cloud) 是全球领先的提供商,各自在功能范围、服务生态系统、性能表现和适用场景上具有独特优势。基于提供的引用[1]-[5],我将从功能、服务和性能三个方面进行结构化对比分析&#…...
GB/T 43887-2024 核级柔性石墨板材检测
核级柔性石墨板材是指以可膨胀石墨为原料、未经改性和增强、用于核工业的核级柔性石墨板材。 GB/T 43887-2024核级柔性石墨板材检测检测指标: 测试项目 测试标准 外观 GB/T 43887 尺寸偏差 GB/T 43887 化学成分 GB/T 43887 密度偏差 GB/T 43887 拉伸强度…...
ffmpeg(三):处理原始数据命令
FFmpeg 可以直接处理原始音频和视频数据(Raw PCM、YUV 等),常见场景包括: 将原始 YUV 图像编码为 H.264 视频将 PCM 音频编码为 AAC 或 MP3对原始音视频数据进行封装(如封装为 MP4、TS) 处理原始 YUV 视频…...
