基于ASN.1的RSA算法公私钥存储格式解读

news2025/6/12 16:09:12

1.概述

RFC5958主要定义非对称密钥的封装语法,RFC5958用于替代RFC5208。非对称算法会涉及到1对公私钥,例如按照RSA算法,公钥是n和e,私钥是d和n。当需要将公私钥保存到文件时,需按照一定的格式保存。本文主要定义公私钥保存到文件的语法。目前私钥封装到文件的规范有PKCS#1和PKCS#8,其中主流为PKCS#8。公钥封装通常兼容X.509规范。本文基于RSA算法进行简单说明。

2.PKCS#8私钥

2.1私钥格式

在RFC5958中,私钥的ASN.1语法如下(ASN.1语法可参考之前的文章)

OneAsymmetricKey ::= SEQUENCE {
	version 						 Version,
	privateKeyAlgorithm		PrivateAlgorithmIdentifier,
	privateKey						PrivateKey
	attributes 				[0] Attributes OPTIONAL,
	...,
	[[2:publickey			[1] PublicKey OPTIONAL]],
	...
}
PrivateKeyInfo ::= OneAsymmetricKey

2.2 参数说明

Version ::= INTEGER { v1(0),v2(1)}。Version值为0或者1,当值为0时,私钥格式遵循RFC5208。RFC5208中对私钥的定义如下:

PrivateKeyInfo ::= SEQUENCE {
	version							Version,
	privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
	privateKey					 PrivateKey
	attributes			[0]	 IMPLICIT Attributes OPTIONAL
}

Version ::= INTEGER
PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
PrivateKey ::= OCTET STRING
Attributes ::= SET OF Attributes

在非对称算法为RSA非加密模式时,PrivateKeyAlgorithmIdentifier定义在RFC5280,定义如下:

AlgorithmIdentifier ::= SEQUENCE {
	algorithm		OBJECT IDENTIFIER,
   parameters		ANY DEFINED BY algoarithm OPTIONAL
}

algorithm的定义在RFC8017 A.1,值为pkcs-1 1,parameters的类型为NULL。pkcs-1 1的值在RFC8017 Appendix C
在这里插入图片描述

PrivateKey定义在PKCS#1(RFC8017 A.1.2 RSA Private Key Syntax),定义如下:

RSAPrivateKey ::=SEQUENCE {
	version					Version,
	modulus					INTEGER, --n
	publicExponent  INTEGER, --e
	privateExponent INTEGER, --d
	prime1					 INTEGER, --p
	prime2					 INTEGER, --q
	exponent1			  INTEGER,--d mod (p-1)
	exponent2			  INTEGER,--d mod (q-1)
	coefficient			 INTEGER, -- (inverse of q) mod p
	otherPrimeInfos	 OtherPrimeInfos OPTIONAL
}

相关参数含义请查看RSA算法原理。

Attributes等参数为可选值,未深入研究。
因此,当version为0时,私钥格式应如下:

PrivateKeyInfo ::= SEQUENCE {
	version							Version,
	privateKeyAlgorithm ::= SEQUENCE {
			algorithm		OBJECT IDENTIFIER,
			parameters		ANY DEFINED BY algoarithm OPTIONAL
		 }
	privateKey					 ::= OCTET STRING
		RSAPrivateKey ::= SEQUENCE {
			version					Version,
			modulus					INTEGER, --n
			publicExponent  INTEGER, --e
			privateExponent INTEGER, --d
			prime1					 INTEGER, --p
			prime2					 INTEGER, --q
			exponent1			  INTEGER,--d mod (p-1)
			exponent2			  INTEGER,--d mod (q-1)
			coefficient			 INTEGER, -- (inverse of q) mod p
			otherPrimeInfos	 OtherPrimeInfos OPTIONAL
		}
	attributes			[0]	 IMPLICIT Attributes OPTIONAL
}

3.X.509公钥

在RFC5280中对公钥的定义如下:

SubjectPublicKeyInfo ::= SEQUENCE {
	algorithm 				AlgorithmIdentifier,
	subjectPublicKey BIT STRING
}

其中AlgorithmIdentifier和私钥中定义相同(见本文2.2章节)
subjectPublicKey定义在RFC8017 A.1.1

RSAPublicKey ::= SEQUENCE {
	modulus					INTEGER, --n
	publicExponent	 INTEGER --e
}

4.文件格式说明

原始公私钥和证书文件应以ASN.1进行编码,编码后的文件是二进制格式。为便于查看,通常会对ASN.1原始编码进行base64并添加头尾信息,形成文本存储格式,此类文件即为PEM文件,通常以.pem、.cer、.key等格式保存。第五章节将详细说明。

5.实践&验证

本章主要基于openssl 3.1版本进行实践,以验证上述理解是否正确。注意:不同版本的openssl生成的公私钥遵循的规范可能有一定差异。尤其是1.X版本

5.1 公钥

我们通过openssl生成公私钥,命令如下
openssl genpkey -algorithm RSA -out private.pem -pkeyopt rsa_keygen_bits:2048
默认生成PKCS#8 PEM格式的私钥,如下:
在这里插入图片描述

该文件是以-----BEGIN PRIVATE KEY-----为头,-----END PRIVATE KEY-----结尾,中间部分即为PKCS#8私钥的ASN.1原始编码的BASE64后内容。可通过如下步骤进行验证:

  1. 将中间部分复制到新文件中,新文件命名为111.txt
    在这里插入图片描述

2.对111.txt中的内容进行base64解码后,以文本形式打开将是乱码
在这里插入图片描述

在这里插入图片描述

3.通过如下命令
openssl rsa -in private.pem -outform DER -out private.der
将PEM格式的私钥转换为ASN.1原始编码的DER格式。
在这里插入图片描述

4.对比转换后的111.txt文件和通过openssl生成的private.der文件,可看到2个文件完全一致。
在这里插入图片描述

通过hexview打开private.pem可以看到原始ASN.1编码
在这里插入图片描述

为便于后续分析,我们使用专业解析工具ASN.1 Editor打开private.pem或者private.der文件,以ASN.1编码形式查看,如下图(关于ASN.1如何理解,请阅读上篇文章)
在这里插入图片描述

在2.1章节总结,当version为0时,私钥格式为

PrivateKeyInfo ::= SEQUENCE {
	version							Version,
	privateKeyAlgorithm ::= SEQUENCE {
			algorithm		OBJECT IDENTIFIER,
			parameters		ANY DEFINED BY algoarithm OPTIONAL
		 }
	privateKey					 ::= OCTET STRING
		RSAPrivateKey ::= SEQUENCE {
			version					Version,
			modulus					INTEGER, --n
			publicExponent  INTEGER, --e
			privateExponent INTEGER, --d
			prime1					 INTEGER, --p
			prime2					 INTEGER, --q
			exponent1			  INTEGER,--d mod (p-1)
			exponent2			  INTEGER,--d mod (q-1)
			coefficient			 INTEGER, -- (inverse of q) mod p
			otherPrimeInfos	 OtherPrimeInfos OPTIONAL
		}
	attributes			[0]	 IMPLICIT Attributes OPTIONAL
}

对照解析如下:
1.整个文件就是1个SEQUENCE的TLV。T为30,指明是个SEQUENCE。L是82 04 BD,指明V的长度为0x04BD,即1213个字节
在这里插入图片描述

2.随后是SEQUENCE的值内容。内容区应包含三个部分1个Version、1个SEQUENCE、1个OCTET STRING,其中Version为0,如下图,符合预期
在这里插入图片描述

3.SEQUENCE为privateKeyAlgorithm。包含1个类型为OBJECT IDENTIFIER的algorithm和1个parameters。如下图,30为SEQUENCE的T,0D为SEQUENCE的L,06为algorithm的L,09为algorithm的长度,algorithm的值为2A 86 48 86 F7 0D 01 01 01,共9个字节,且值符合2.1章节的分析。parameters为NULL类型
在这里插入图片描述

4.OCTET STRING为privateKey,即存储的私钥信息。首先是个SEQUENCE包裹内容,SEQUENCE中包含9个INTEGER,otherPrimeInfos为可选的,本次证书里没有该内容。
在这里插入图片描述

5.2 公钥

通过openssl命令从私钥中生成公钥,命令如下:
openssl rsa -pubout -in private.pem -out public.pem
同样适用ASN.1 Editor打开公钥public.pem。可以看到公钥整体有1个SEQUENCE,SEQUENCE中包含1个SEQUENCE和1个BIT_STRING,BIT_STRING中是1个SEQUENCE,符合第3章节的X.509的公钥结构。
在这里插入图片描述

具体解读,不再赘述。可参考5.1章节对私钥的解读,按照相同方式解读。

6.总结

本文在前4个章节主要基于相关RFC文档的解读,简单介绍RSA算法的公私钥如何保存到文件中,即RFC相关文档定义了公私钥保存的格式,随后使用ASN.1编码对相关内容进行编码,并按照RFC定义的格式保存到文件中。实际保存到文件中还涉及两种格式:1.原始ASN.1编码以二进制文件格式保存到文件中。2.对原始ASN.1进行BASE64编码,随后添加一个可文本阅读的头和尾,形成pem格式的可阅读文本文件。在第5章节结合OPENSSL实际生成的公私钥进行验证。
本文仅介绍了最简单也是最常见情况下的公私钥存储情况,不涉及加密保存的公私钥等场景。若需深入研究可继续阅读本文中罗列的RFC文档。

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

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

相关文章

002_Anaconda的安装与使用

Python的开发环境 官方介绍:Anaconda,中文大蟒蛇,是一个开源的Python发行版本,其包含了conda、Python等180多个科学包及其依赖项。 比较抽象,看不懂没有关系,慢慢往下看。 很多学习python的初学者甚至学…

Android 触摸事件分离原理

什么是触摸事件分离? 屏幕上存在多个窗口时,多指触摸的情况下,多个手指的触摸事件可以分给不同的窗口,以下面的图为例,第一个手指按下,window1可以响应这个事件,第二个手指按下(第一…

Vue的学习 —— <vue组件>

目录 前言 正文 一、选项式API与组合式API 二、生命周期函数 1、onBeforeMount() 2、onMounted() 3、onBeforeUpdate() 4、onUpdated() 5、onBeforeUnmount() 6、onUnmounted() 三、组件之间的样式冲突 四、父组件向子组件传递数据 1、定义props 2、静态绑定props…

Elasticsearch 在滴滴的应用与实践

滴滴 Elasticsearch 简介 简介 Elasticsearch 是一个基于 Lucene 构建的开源、分布式、RESTful 接口的全文搜索引擎,其每个字段均可被索引,且能够横向扩展至数以百计的服务器存储以及处理 TB 级的数据,其可以在极短的时间内存储、搜索和分析大…

文章解读与仿真程序复现思路——中国电机工程学报EI\CSCD\北大核心《集装箱海港级联物流-能源耦合系统协同优化方法 》

本专栏栏目提供文章与程序复现思路,具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

jenkins配置不同版本nodeJS,保姆级叫你配置

问题描述:公司jenkins被改了nodejs版本适配其他项目导致以前的项目构建失败,原因就是nodejs版本太高或太低导致,这里教大家不去更改服务器默认版本,当需要特殊版本直接在jenkins里配置即可。 过程 1、安装nodeJS插件 1.1点击管…

XML文件转TXT文件 yolo标签转换(代码可直接使用) 可批量转换

像这样的xml文件,我们可以通过代码批量转换为txt文件格式: 新建一个xml2txt.py文件, 上代码,直接复制粘贴 import xml.etree.ElementTree as ET import osdef convert(size, box):x_center (box[0] box[1]) / 2.0y_center (box…

2020 年第一届辽宁省大学生程序设计竞赛

比赛经历:摸鱼划水了一个多小时又是只会签到,看来还得提升自己的解题能力写了六题 补题:E线段树维和区间平方和,比较经典好久没写过线段树了傻了,注意维护lazy J计算几何,看来得提上日程了,用叉…

0.98T优于10米高程DEM数据

我们在《全球30米100%水陆覆盖高程》一文中,为大家分享了全球100%覆盖,且包括海底高程的30米DEM数据。 该数据虽然全球无死角覆盖,但分辨率只有30米。 这里,再为大家分享一个优于10米的高程数据,但目前仅覆盖全国范围…

The 13th Shandong ICPC Provincial Collegiate Programming Contest

The 13th Shandong ICPC Provincial Collegiate Programming Contest The 13th Shandong ICPC Provincial Collegiate Programming Contest A. Orders 题意:有n个订单, 每日可生产k个产品,每个订单给出交付日和交付数量,是否能…

每日一练 2024.5.16(补 2024.5.14)

题目&#xff1b; 我们定义 arr 是 山形数组 当且仅当它满足&#xff1a; arr.length > 3存在某个下标 i &#xff08;从 0 开始&#xff09; 满足 0 < i < arr.length - 1 且&#xff1a; arr[0] < arr[1] < ... < arr[i - 1] < arr[i]arr[i] > arr…

泛微E9开发 自动获取日期

选择开始日期&#xff0c;自动获取指定天数后的结束日期 1、功能背景2、展示效果3、实现方法 1、功能背景 用户选择开始日期&#xff0c;系统自动带出结束日期&#xff0c;如需要带出6天后的结束日期&#xff0c;下图所示&#xff0c;5月14日到5月20日是一个周期&#xff0c;用…

Linux-centos下安装ffmpeg的详细教程

源安装 第一种方式&#xff1a; . 首先需要安装yum源&#xff1a; 这个源安装的ffmpeg版本是3.4 yum install epel-release yum install -y https://mirrors.ustc.edu.cn/rpmfusion/free/el/rpmfusion-free-release-7.noarch.rpm然后可以安装ffmpeg yum install -y ffmpeg ff…

电阻式传感器

电阻式传感器是一种将非电学量&#xff08;如温度、压力、位移等&#xff09;转换为电阻变化的传感器。它大致分为电阻应变式传感器、压阻式传感器和变阻式传感器三类。 电阻式传感器的优点包括结构简单、成本低廉、稳定性好&#xff0c;适用于多种环境。但它们也有局限性&…

第十四届蓝桥杯大赛软件赛国赛C/C++ 大学 B 组 AB路线

//bfs 1000100010不会超时 #include<bits/stdc.h> using namespace std; #define int long long const int n1e311; int a,b,c,h[n][n][12],k[4][2]{0,1,0,-1,1,0,-1,0}; char t[n][n]; struct s {int x,y,z,w; }; signed main() {ios::sync_with_stdio(false);cin.t…

VMware虚拟机-安装程序无法自动安装virtual machine......_windows server 2008 R2

系统版本&#xff1a;windows server 2008 R2 问题-安装程序无法自动安装virtual machine… 在使用虚拟机安装windows server 2008 R2系统中&#xff0c;安装VMware Tools工具安祖啊寄给你失败&#xff0c;提示安装程序无法自动安装virtual machine…&#xff0c;必须手动安装…

lazada、shopee新店铺如何快速出单?自养号补单测评实战操作指南

作为一家Lazada、虾皮新店铺&#xff0c;要快速出单&#xff0c;需要采取一些策略和措施。以下是一些可以考虑的方法&#xff1a; 一、优化产品信息 确保您的产品信息完整、准确、清晰&#xff0c;并且可以吸引潜在客户。这包括商品标题、描述、图片、价格等。 二、优化店铺…

其他自动化工程师都在偷偷学习AI技术,你再不学就落后了!一篇文章教会你使用AI!

其他自动化工程师都在偷偷学习AI技术&#xff0c;你再不学就落后了&#xff01;一篇文章教会你使用AI&#xff01; 哈喽&#xff0c;大家好&#xff0c;我是小叔。了解小叔的朋友都清楚&#xff0c;我从来都不是标题党&#xff0c;我只会用美女图片来吸引你们&#x1f602;&am…

如何管理研发人员

在日益激烈的市场竞争中&#xff0c;企业的核心竞争力往往取决于其技术创新能力和研发实力。然而&#xff0c;随着企业研发的深入和技术的积累&#xff0c;研发人员泄密的风险也愈发严重。如何防止研发人员泄密&#xff0c;已经成为企业面临的重要问题。本文将从加强员工保密意…

前端简史之崛起:Router迁鼎

引 &#x1f4a1; Ajax 的出现&#xff0c;带来了 jQuery 时代&#xff1b;Node技术的发展&#xff0c;带来了前端工程化进阶&#xff1b;如果说前面二者是带来技术的革命&#xff0c;那么前端路由方案的多样化则带来了用户体验的升级以及项目管理的优化。 课程简介 《前端简史…