Rust: 加密算法库 ring 如何用于 RSA 数字签名?
本来用 rsa 库基本搞定,但文心一言建议改用 ring 库。原因是 rsa 库已经放弃维护,而 ring 库性能公认很好。但是如何进行 RSA 数字签名,网上几乎查不到这方面材料。仔细查看了 ring 库的源代码和代码注释,终于完成趟坑。总结一下供大家参考。
1. 生成密钥文件
用 RSA数字签名算法时,如何从磁盘文件加载密钥?这需要用 openssl 工具。这个工具如何下载安装不再赘述。
1.1 PEM 格式密钥文件
PEM(Privacy-Enhanced Mail)直译为“保密邮件”,但在此上下文中,它主要指的是一种用于存储加密密钥和证书的文件格式。PEM格式是一种基于ASCII编码的密钥和证书的存储格式,说白了就是文本文件,广泛用于安全领域,特别是在SSL/TLS协议中的证书和密钥管理。
以下是关于PEM格式密钥文件的详细解释:
-
文件内容:
- PEM文件可以包含公钥、私钥、证书等敏感信息。
- 这些信息通常以Base64编码的形式存储,并且包含了起始标记和结束标记,以便于识别和区分不同类型的密钥和证书。
-
文件结构:
- PEM文件的内容通常以
-----BEGIN <标签>-----
开头,以-----END <标签>-----
结束。 <标签>
部分用于指示文件内容的类型,例如CERTIFICATE
表示证书,PRIVATE KEY
表示私钥,等等。- Base64编码的数据位于这两个标记之间,是实际的密钥或证书内容。
- PEM文件的内容通常以
-
应用场景:
- PEM格式的文件在建立安全的网络连接(如HTTPS)时用于证明服务器的身份。
- 它们也用于对数据进行加密和解密,或者进行数字签名。
- PEM文件还可以用于构建完整的证书链,以验证服务器证书的有效性。
-
安全性:
- 由于PEM文件中包含了敏感的密钥和证书信息,因此需要采取一些措施来保护其安全性。
- 可以通过严格限制访问权限、使用加密算法进行加密存储、以及采取安全通道和安全设备来传输和存储PEM文件,以防止中间人攻击和数据泄露。
-
与其他格式的转换:
- PEM格式与其他格式(如DER、PKCS#7、PKCS#12等)之间的转换是常见的需求。
- 可以使用OpenSSL工具或其他相关工具来完成这些转换。
综上所述,PEM是一种重要的密钥和证书存储格式,在安全通信和数据保护方面发挥着关键作用。了解PEM格式的结构和应用场景,有助于更好地管理和保护敏感信息的安全性。
1.2 生成 PEM 格式的 RSA 密钥文件
下面 openssl 命令可以生成一个名为private_key.pem
的密钥文件。该文件可以用记事本打开查看结果。
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
1.3 从 RSA 密钥文件导出 RSA 公钥文件
下面 openssl 命令可以从私钥文件 private_key.pem
中提取出公钥文件 public_key.pem
。
openssl rsa -pubout -in private_key.pem -out public_key.pem
1.4 PEM 密钥文件的使用
我曾用过 C++ 的 Crypto 库,这个库可以直接使用 PEM 密钥文件加载密钥。我以为 ring 库也是如此,结果非常失望。如果哪位朋友能用 ring 库直接加载,希望能告知,本人不胜感谢!
1.5 生成 PKCS#8 密钥
私钥文件用于签名。ring 库可以导入PKCS#8 规格的密钥,要求密钥文件按照 pk8
格式保存。ring 库的源代码注释提供了数字签名的方法。首先 ring 库需要的 PKCS#8 密钥证书的生成方法,代码如下:
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537 | openssl pkcs8 -topk8 -nocrypt -outform der > rsa-2048-private-key.pk8
1.6 导出公钥文件
公钥文件用于验证数字签名。ring 库可以读取 DER 格式的公钥文件。但 ring 的源代码等文档并没提供如何获得这份文件。经过反复尝试,发现从私钥文件抽取公钥文件分两步进行:首先生成 PEM 格式公钥文件,然后再转换成 DER 格式的公钥文件。命令如下:
openssl rsa -pubout -in rsa-2048-private-key.pk8 -inform DER -outform PEM -out rsa-2048-public-key.pem
openssl rsa -pubin -in rsa-2048-public-key.pem -inform PEM -RSAPublicKey_out -outform DER -out rsa-2048-public-key.der
1.7 关于 PEM、DER、PK8 格式的说明
PEM、DER、PK8(通常指的是PKCS#8私钥格式,但为简化讨论,这里将PK8视为PKCS#8的私钥部分的简称)是三种常见的密钥文件格式,它们各自有不同的特点和应用场景。以下是关于这三种密钥文件格式以及它们名字来历的详细说明:
1.7.1 PEM(Privacy-Enhanced Mail)
- 来历:
- PEM格式最早由美国互联网工程任务组(IETF)在1987年的RFC 1421中定义。
- 最初是为了解决电子邮件的加密和签名问题而设计的。
- 特点:
- PEM格式是一种基于ASCII编码的密钥和证书的存储格式。
- 文件通常以“.pem”为后缀名。
- 可以包含公钥、私钥、证书等敏感信息。
- 使用Base64编码,并且包含了起始标记和结束标记,以便于识别和区分不同类型的密钥和证书。
- 具有良好的可读性和可编辑性。
1.7.2 DER(Distinguished Encoding Rules)
- 来历:
- DER是一种二进制编码格式,常用于证书和密钥的存储和传输。
- 它是ASN.1(Abstract Syntax Notation One)标准的一部分,由国际电信联盟(ITU-T)定义。
- 特点:
- DER文件通常以“.der”或“.cer”(在某些上下文中,特别是Windows平台上,“.cer”可能用于表示DER编码的证书文件)为后缀名。
- 与PEM格式相比,DER格式更加紧凑和高效,因为它使用二进制编码而不是Base64编码。
- DER格式的文件不易于阅读和编辑,通常需要专业的工具才能查看和解析。
1.7.3 PKCS#8(Private-Key Cryptography Standards #8)
- 来历:
- PKCS#8是由RSA实验室发布的一种标准,用于存储私钥信息。
- 它是PKCS(Public-Key Cryptography Standards)系列标准的一部分。
- 特点:
- PKCS#8定义了私钥的语法,包括如何对私钥进行编码和加密。
- 提供了未加密和加密两种格式的私钥存储方式。
- 未加密的私钥信息通常以明文形式存储(但编码为Base64或其他格式以方便存储和传输),而加密的私钥信息则使用密码短语或其他加密算法进行保护。
- 常与OpenSSL等工具配合使用。
- 在较新版本的OpenSSL中,生成的RSA私钥默认符合PKCS#8的PrivateKeyInfo结构。
需要注意的是,虽然PEM、DER和PKCS#8在密钥和证书的存储和管理中扮演着重要角色,但它们并不是互斥的。实际上,它们可以相互转换,并且可以在不同的应用场景中共同使用。例如,可以使用OpenSSL等工具将PEM格式的私钥转换为DER格式,或者将PKCS#8格式的私钥转换为PKCS#1格式的私钥(尽管PKCS#1主要用于公钥的存储)。
2. 实现签名与验证的源代码
下面直接贴 ring 提供的示例代码:
Cargo.toml 添加下面库:
ring = "0.17.8"
程序源代码:
use ring::{rand, rsa, signature};fn sign_and_verify_rsa(private_key_path: &std::path::Path,public_key_path: &std::path::Path)-> Result<(), MyError> {
// Create an RSA keypair from the DER-encoded bytes. This example uses
// a 2048-bit key, but larger keys are also supported.
let private_key_der = read_file(private_key_path)?;
let key_pair = rsa::KeyPair::from_der(&private_key_der).map_err(|_| MyError::BadPrivateKey)?;// Sign the message "hello, world", using PKCS#1 v1.5 padding and the
// SHA256 digest algorithm.
const MESSAGE: &'static [u8] = b"hello, world";
let rng = rand::SystemRandom::new();
let mut signature = vec![0; key_pair.public().modulus_len()];
key_pair.sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature).map_err(|_| MyError::OOM)?;// Verify the signature.
let public_key =signature::UnparsedPublicKey::new(&signature::RSA_PKCS1_2048_8192_SHA256,read_file(public_key_path)?);
public_key.verify(MESSAGE, &signature).map_err(|_| MyError::BadSignature)
}#[derive(Debug)]
enum MyError {IO(std::io::Error),BadPrivateKey,OOM,BadSignature,
}fn read_file(path: &std::path::Path) -> Result<Vec<u8>, MyError> {use std::io::Read;let mut file = std::fs::File::open(path).map_err(|e| MyError::IO(e))?;let mut contents: Vec<u8> = Vec::new();file.read_to_end(&mut contents).map_err(|e| MyError::IO(e))?;Ok(contents)
}
我加了一段测试程序供参考:
#[test]
fn test2() {let pkcs8 = read_file(std::path::Path::new("rsa-2048-private-key.pk8")).unwrap();let key_pair = rsa::KeyPair::from_pkcs8(&pkcs8).unwrap();const MESSAGE: &'static [u8] = b"hello, world";let rng = rand::SystemRandom::new();let mut signature = vec![0; key_pair.public().modulus_len()];key_pair.sign(&signature::RSA_PKCS1_SHA256, &rng, MESSAGE, &mut signature).map_err(|_| MyError::OOM).unwrap();println!("\nsignature:{:?}", signature);let public_key = signature::UnparsedPublicKey::new(&signature::RSA_PKCS1_2048_8192_SHA256,read_file(std::path::Path::new("rsa-2048-public-key.der")).unwrap(),);println!("\npublic_key = {:?}", public_key);public_key.verify(MESSAGE, &signature).unwrap();
}
3. 心得体会
- 阅读开源库的源代码可以解决文档不足的问题。
- 希望多展开交流,加快学习进步!
相关文章:
Rust: 加密算法库 ring 如何用于 RSA 数字签名?
本来用 rsa 库基本搞定,但文心一言建议改用 ring 库。原因是 rsa 库已经放弃维护,而 ring 库性能公认很好。但是如何进行 RSA 数字签名,网上几乎查不到这方面材料。仔细查看了 ring 库的源代码和代码注释,终于完成趟坑。总结一下供…...
Matplotlib 网格线
Matplotlib 网格线 Matplotlib 是一个强大的 Python 绘图库,广泛用于数据可视化。在 Matplotlib 中,网格线是一种常用的辅助工具,用于增强图表的可读性和美观性。本文将详细介绍如何在 Matplotlib 中添加和使用网格线。 1. 简介 网格线是在…...

钉钉机器人禅道消息通知@指派人
钉钉、禅道怎么设置webhook? 点击查看:获取自定义机器人 Webhook 地址 在禅道上配置钉钉机器人webhook,使用管理员账号登录,找到通知设置 添加webhook 添加webhook所需要的数据即可 webhook设置,根据自己的实际…...

我的新书出版啦!和大家聊聊写书的酸甜苦辣
我的新书出版啦!小伙伴们问是不是赚翻了? 大家好,我是码哥。我的新书《Redis 高手心法》出版后(2024 年 8 月份出版),有一些小伙伴问了我一些问题: 写书是不是赚了很多钱?我也想写…...

【福建医科大学附属第一医院-注册安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞 …...
第二届新生程序设计竞赛热身赛(C语言)
A:饥饿的XP XP迷失在X星球,他醒来时已经很久很久很久没有吃过东西了。他突然发现身边有一张地图,上面有X星球上每一个食物供给点的位置。太好了,XP跳了起来。他决定先把肚子填饱再去寻找其他伙伴。现在已知XP的位置(X, Y),以及他的…...
WebSocket和HTTP请求的区别
1. 连接方式 HTTP请求:基于“请求-响应”模式。每次通信都要重新建立连接,客户端发送请求后服务器返回响应,连接就断开了。这种模式通常适合不频繁更新的数据,如静态页面的加载。WebSocket:支持长连接,连接…...

【Python · Pytorch】人工神经网络 ANN(中)
【Python Pytorch】人工神经网络 ANN(中) 6. 反向传播6.1 梯度下降法6.1.1 线搜索方法6.1.2 微分 & 导数6.1.3 偏导数6.1.4 Jacobian矩阵6.1.5 梯度 & 梯度下降法按维度介绍 6.1.6 面临挑战平原现象 & 振荡现象局部最小值鞍点梯度消失梯度爆…...
穷举vs暴搜vs深搜vs回溯vs剪枝 算法专题
一. 全排列 全排列 class Solution {List<List<Integer>> ret;List<Integer> path;boolean[] check;public List<List<Integer>> permute(int[] nums) {ret new ArrayList<>();//存放结果path new ArrayList<>();存放每个路径的…...

Uni-App-02
条件编译 条件编译概念 不同的运行平台终归有些专有的特性,无法实现跨平台完全兼容,例如:微信小程序导航栏右上角的关闭图标。 uni-app提供了一种“条件编译”机制,可以针对特定的平台编译执行特定的代码,否则不执行。…...

在做题中学习(72):最小栈
解法:pair<int,int>解决 思路:stack里存pair,push时,first存当前值,而每次push都要更新pair的second,使它成为更小值,最后的getmin,只用取top().second即可拿到最小值。 cla…...

详解软件设计中分库分表的几种实现以及应用示例
详解软件设计中分库分表的几种实现以及应用示例https://mp.weixin.qq.com/s?__bizMzkzMTY0Mjc0Ng&mid2247485108&idx1&sn8b3b803c120c163092c70fa65fe5541e&chksmc266aaa1f51123b7af4d7a3113fe7c25daa938a04ced949fb71a8b7773e861fb93d907435386#rd...
随着飞行汽车的亮相,在环保方面有什么保护措施吗
飞行汽车具备环保潜力,采用电动或混合动力系统减少污染,并拓展应用场景。多家企业布局,沃飞长空作为国内eVTOL(电动垂直起降航空器)研发的领先企业,在环保这一点做的非常到位,AE200采用纯电动力系统,零碳排放,静默飞行…...

docker安装、设置非sudo执行、卸载
安装 sudo snap install docker 设置docker非sudo执行 sudo groupadd docker sudo usermod -aG docker $USER newgrp docker sudo chown root:docker /var/run/docker.sock 卸载docker 1.删除docker及安装时自动安装的所有包 apt-get autoremove docker docker-ce docker-…...
WebSocket简单使用
1.WebSocket 简介 WebSocket 是一种网络通信协议,提供了在单个TCP连接上进行全双工通信的能力。这意味着客户端和服务器可以同时发送和接收数据,而不需要等待对方的回应。WebSocket 协议在2011年成为国际标准,并且被大多数现代浏览器所支持。…...

【FinalShell问题】FinalShell连接虚拟机超时问题
问题描述: 打开fianlshell连接之前设置好的SSH连接(Linux),结果连接不上,并出现提示:java.net.ConnectException: Connection timed out: connect,说明虚拟机连接超时。 问题解决:…...
Matplotlib可视化——三维图与莫比乌斯带可视化
实验名称 Matplotlib中的三维图绘制:莫比乌斯带的可视化 实验目标 三维的点和线三维轮廓图线框图和曲面图曲面三角形 举例:莫比乌斯带的可视化实验主要使用的Python库 名称版本简介Numpy1.19.5数组运算Matplotlib3.3.4数据可视化实验适用的对象 学习对象:本科学生、研究生…...

【PyCharm配置Conda的虚拟环境】
conda create了一个新的虚拟环境,想在PyCharm里面使用这个环境,但是怎么都添加不上。 解决办法,把conda executable选择为conda安装目录下的condabin下的conda.bat文件,成功!...
今日总结10.31
BIO、NIO 和 AIO 的区别 BIO(Blocking I/O,同步阻塞I/O)、NIO(Non-blocking I/O,同步非阻塞I/O)和AIO(Asynchronous I/O,异步非阻塞I/O)是Java中的三种不同的I/O模型&am…...

2024年【汽车修理工(高级)】考试题及汽车修理工(高级)最新解析
题库来源:安全生产模拟考试一点通公众号小程序 2024年【汽车修理工(高级)】考试题及汽车修理工(高级)最新解析,包含汽车修理工(高级)考试题答案和解析及汽车修理工(高级…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
反向工程与模型迁移:打造未来商品详情API的可持续创新体系
在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...