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年【汽车修理工(高级)】考试题及汽车修理工(高级)最新解析,包含汽车修理工(高级)考试题答案和解析及汽车修理工(高级…...

17. 从尾到头打印链表
文章目录 QuestionIdeasCode Question 输入一个链表的头结点,按照 从尾到头 的顺序返回节点的值。 返回的结果用数组存储。 数据范围0≤链表长度 ≤1000。 样例 输入:[2, 3, 5] 返回:[5, 3, 2] Ideas 直接遍历链表,然后倒序…...

有没有噪音低的宠物空气净化器推荐?希喂、IAM性能PK
有一说一,随着清洁家电市场的不断发展,市面上的各种清洁家电品类也是越来越多,像是吸尘器、洗地机、扫地机等等这些产品估计大家都很熟悉了。 但!如果你家也跟我家一样也是养了几只猫猫狗狗,那你就会发现到࿰…...

EasyExcel文件导入与导出
EasyExcel是一个为了简化Excel操作而生的开源库,它可以帮助我们以简洁的代码完成Excel文件的导入和导出。 以下是使用EasyExcel进行文件导入和导出的示例代码: 导入(读取)Excel文件: import com.alibaba.excel.Easy…...

【成都新篇】龙信科技电子取证实验室,引领科技取证新时代
文章关键词:电子数据取证实验室、手机取证、介质取证、云取证、现场勘查、电子物证 在科技创新的浪潮中,龙信科技成都实验室以其卓越的电子数据取证服务,成为了中西部地区一颗璀璨的明珠。随着新址的搬迁,我们不仅扩大了业务范围…...

Android View
前面我们了解了Android四大组件的工作流程,Android中还存在一个和四大组件地位相同的概念:View,用于向用户页面展示内容。我们经常使用的TextView、Button、ImageView控件等都继承于它,也会自定义View实现自定义效果。View类源码内…...

从一到无穷大 #38:讨论 “Bazel 集成仅使用 Cmake 的依赖项目” 通用方法
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。 文章目录 正文样例代码 正文 Bazel项目引用仅使用Cmake依赖项目,目前业界最为普遍…...

Python飞舞蝙蝠
目录 系列文章 写在前面 完整代码 代码分析 写在后面 系列文章 序号直达链接爱心系列1Python制作一个无法拒绝的表白界面2Python满屏飘字表白代码3Python无限弹窗满屏表白代码4Python李峋同款可写字版跳动的爱心5Python流星雨代码6Python漂浮爱心代码7Python爱心光波代码…...

shodan搜索引擎——土豆片的网安之路
工作原理: 在服务器上部署了各种扫描器,如漏洞扫描器,硬件扫描器,目录扫描器等等,24小时不停的扫描,批量对IP地址扫描 优点:方便,很快得到最新扫描结果,漏洞信息 缺点…...

uniapp 报错Invalid Host header
前言 在本地使用 nginx 反向代理 uniapp 时,出现错误 Invalid Host header 错误原因 因项目对 hostname 进行检查,发现 hostname 不是预期的,所以,报错 Invalid Host header 。 解决办法 这样做是处于安全考虑。但࿰…...

删除 AzureArcSetup 安装程序及提示
删除 AzureArcSetup 安装程序及提示 文章目录 删除 AzureArcSetup 安装程序及提示一、基础环境二、适用场景三、过程和方法 版权声明:本文为CSDN博主「杨群」的原创文章,遵循 CC 4.0 BY-SA版权协议,于2024年10月31日首发于CSDN,转…...