首页 > 其他分享 >一文搞懂系列——PEM文件解析流程

一文搞懂系列——PEM文件解析流程

时间:2024-07-25 16:25:39浏览次数:21  
标签:编码 字节 pem PEM ----- 类型 长度 搞懂 解析

在这里插入图片描述

背景

前几周,协助同事解决了SM2软签名的需求,其流程可参考终于解决了!!! 基于GmSSL的SM2签名算法及思路分享

但是在解决这个问题的过程中,让我想起了一些不好的回忆:曾经在大众项目中,也接触过椭圆曲线算法签名。其中因为平台下发的公钥格式,由于双方理解不一致,导致最终调试很久,并且自己也处于懵懵懂懂的状态

在协助同事解决软签名的过程中,也遇到了类似问题:证书内容与公钥私钥的关系,如何从.pem格式文件中,提取我们需要的公私钥。

而本文的目的就是介绍.pem文件中的数据格式以及如何解析。作为上层应用开发者可能并不需要了解,知道如何调用接口即可。但是对于我而言,这就是我心中的痛,所以我一定要了解:如何从.pem格式的私钥证书中,获取公钥、私钥信息。

有兴趣的朋友不妨可以了解一下。本文将以下列私钥文件举例描述:

xieyihua@xieyihua:~/GmSSL-master$ cat prikey.pem
-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgtJNqd4cc2GtzhhR/
Up73/B5aPXainNVCT3m9Pz09m2ygCgYIKoEcz1UBgi2hRANCAATX3mX8KCvFzcPM
7vB3Ys62UoJFNxreM0RwDxTCBJ00UhnfLTN347ELOQpxeCuWG5spGyacvvlnehN3
nNwtem+V
-----END PRIVATE KEY-----
xieyihua@xieyihua:~/GmSSL-master$

基础内容学习

在分析上述文件前,我们需要了解以下内容。

pem 与 der

  • PEM:Privacy-Enhanced Mail,隐私增强邮件。PEM格式文件后缀通常为".pem"、“.cer”、“.crt”、“.key”,后缀名并不会影响 PEM 格式文件的解析。
  • DER:Distinguished Encoding Rules,可分辩编码规则。DER格式文件后缀通常为 “.der” 和 “.cer”,后缀名并不会影响 DER 格式文件的解析。

其中pemder的关系:

ASN.1 ----->(序列化)-----> DER -----(Base64编码)-----> PEM

即:对ASN.1进行序列化后,得到一个二进制串,这就是DER格式。再将DER格式数据进行base64编码,加上PEM特有的头、尾(本文中-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----),即可得到私钥文件内容。

由上可知,我们只需要逆向解析,得到DER格式数据,按照ASN.1的规则进行解析即可了解文件中的各字段内容。

初识 ANS.1

在现代通信和信息技术领域,数据的精确表示和高效传输是至关重要的。ASN.1(Abstract Syntax Notation One)作为一种国际标准化组织(ISO)和国际电信联盟(ITU)制定的国际标准,提供了一种抽象的方法来描述、编码、解码和传输数据。ASN.1的核心组成部分之一是BER(Basic Encoding Rules),它定义了一种将ASN.1数据结构转换为二进制形式的编码规则。

而DER是BER的特殊版本,主要应用于安全领域中,对一些场景具有唯一性,但是解析规则都是一样的。

BER编码基本格式

BER(Basic Encoding Rules)是一种用于描述ASN.1(Abstract Syntax Notation One)数据的编码规则。BER编码使用一种TLV(Type-Length-Value)的结构方法编码。

即,BER编码的基本结构由以下三个部分组成:

  • 类型域(Type)
  • 长度域(Length)
  • 内容域(Value)

其中类型(Type)部分又有三部分组成:

  • 标签类型(Class)
  • 构造类型(P/C)
  • 标签号(Tag)

其中数据域(Value)也存在两种情况:

  • 单一的数据类型,如intDouble类型;
  • 复杂的自定义类型结构,对于一种数据结构中包含了其它数据结构,往往就是一些简单类型。类似C语言中的结构体。如下:

类型域

类型域(Type)用于标识数据的类型和类别。类型域编码包含三个部分:类(Class)、构造类型(PC, Primitive/Constructed)、和标签号(Tag Number)。下面详细说明这三个部分的编码:

类型域字节的格式如下:

分析:

标签类型有四种,分别是:

  • Universal(通用类别):值为 00。这类数据类型是由ASN.1标准定义的,如整数、布尔值、位串等。它们是通用的,可以在任何上下文中使用。
  • Application(应用类别):值为 01。这类数据类型是特定应用程序定义的,它们在特定的应用上下文中具有特殊的含义。
  • Context-specific(上下文相关类别):值为 10。这类数据类型通常用于结构化数据中的标记字段,它们的含义依赖于特定的上下文或结构。
  • Private(私有类别):值为 11。这类数据类型是为私有的或组织特定的用途而定义的,它们在标准中没有定义,通常由个别组织内部使用。

构造类型有两种,分别是:

  • 原始类型(Primitive):值为0。用于表示ASN.1中的基本数据类型,如INTEGER、OCTET STRING、BOOLEAN等
  • 构造类型(Constructed):值为1。用于表示ASN.1中的复合数据类型,如SEQUENCESETSEQUENCE OFSET OF等。或创建复杂的数据结构。

标签号的作用表示具体的数据类型或结构。它的取值范围有两种:

  1. 简单标签号(0~30)。对于标签号在 0 到 30 之间的情况,直接在类型域的第4-8位表示。例如:
通用类(Universal)布尔类型(Boolean):0000 0001,即 0x01
应用类(Application)整数类型(Integer):0100 0010,即 0x42
  1. 复杂标签号(>=31)。对于标签号大于等于 31 的情况,第4-8位全为 1(即 0b11111),并且标签号以基于 7 位的块形式在后续字节中表示,每个字节的最高位为 1,表示后续有更多字节,最后一个字节的最高位为 0。例如:
标签号 31:0b1111 1111 0011 1111,即 0x1F 0x1F

标签号 128:0b1111 1111 1000 0001 0000 0000,即 0x1F 0x81 0x00

ASN.1 已定义的标签号如下:

类型标签号
BIT STRING00000011(0x03)
BOOLEAN00000001(0x01)
INTEGER00000010(0x02)
Null00000101(0x05)
对象标识符00000110(0x06)
八进制字符串00000100(0x04)
BMPString00011110(0x1E)
IA5String00010110(0x16)
PrintableString00010011(0x13)
TeletexString00010100(0x14)
UTF8String00001100(0x0C)
SEQUENCE00110000(0x30)
序列00110000(0x30)
SET00110001(0x31)
SET OF00110001(0x31)

长度域

在 BER(Basic Encoding Rules)编码中,长度域用于指示随后的值域(Value)的长度。长度域的编码有主要两种形式:短形式长形式。下面是对这两种形式的详细说明:

  • 短形式

短形式用于表示长度小于 128 字节(即 0 到 127)的情况。在这种形式中,长度域仅占一个字节。该字节的最高位(第八位)为 0,低七位表示长度的值。例如:

若长度为 5,则长度域为 0000 0101(即 0x05)。

若长度为 127,则长度域为 0111 1111(即 0x7F)。
  • 长形式

长形式用于表示长度大于等于 128 字节的情况。在这种形式中,长度域的第一个字节的最高位(第八位)为 1,低七位表示后续长度字节的个数。例如:

若长度为 128,则长度域为 1000 0001(表示后续有 1 个字节)加上 1000 0000(表示长度为 128),即 0x81 0x80。

若长度为 300,则长度域为 1000 0010(表示后续有 2 个字节)加上 0000 0001 0010 1100(即 300),即 0x82 0x01 0x2C。

内容域

在 BER(Basic Encoding Rules)编码中,内容域(Value)包含实际的数据信息,其编码方式取决于数据的类型。不同数据类型有不同的编码规则。以下是一些常见数据类型的编码方式:

  • 布尔型(BOOLEAN)

布尔型值使用一个字节表示:TRUE 编码为 0xFF、FALSE 编码为 0x00;

  • 整型(INTEGER)

整型值以大端顺序(高字节在前)编码,使用最少的字节数来表示值。如果最高有效位为 1,则需要在前面加一个 0x00 以避免符号扩展。例如:

0 编码为 0x00
127 编码为 0x7F
128 编码为 0x00 0x80
-1 编码为 0xFF
  • 位串(BIT STRING)

位串由一个初始字节和实际数据组成。初始字节表示未使用的位数。实际数据按字节顺序排列。例如:

0x01101011(假设全用)编码为 0x00 0x6B
0x01101010(未使用1位)编码为 0x01 0x6A
  • 字符串(OCTET STRING)

字符串(八位字节串)按字节顺序直接编码。例如:

"Hello" 编码为 0x48 0x65 0x6C 0x6C 0x6F
  • NULL

NULL 值没有内容,其长度为 0。因此,NULL 值的编码只是标记和长度,值为空。例如:

NULL 编码为 0x05 0x00
  • 对象标识符(OBJECT IDENTIFIER)

对象标识符使用变量长度编码。前两个节点由 (X * 40) + Y 公式表示,后续节点使用基于 7 位的块形式编码,最高位为 1 表示有后续字节。例如:

1.2.840.113549 编码为 0x2A 0x86 0x48 0x86 F7 0x0D(1*40 + 2 = 42, 840 = 0x86 0x48, 113549 = 0x86 0xF7 0x0D)
  • 序列(SEQUENCE)

序列包含一个或多个元素,每个元素按其类型编码,然后依次排列。例如,一个包含一个整数和一个字符串的序列:

整数:42 编码为 0x02 0x01 0x2A
字符串:"Hi" 编码为 0x04 0x02 0x48 0x69
整个序列编码为:0x30(标记) 0x07(长度) 0x02 0x01 0x2A(整数) 0x04 0x02 0x48 0x69(字符串)

分析

通过以上基础概念的了解,我们可以尝试分析pem文件了。

  1. 查看pem文件内容,通过base64反编码,获取der数据。在线base64编解码

即der数据为:

308193020100301306072A8648CE3D020106082A811CCF5501822D047930770201010420B4936A77
871CD86B7386147F529EF7FC1E5A3D76A29CD5424F79BD3F3D3D9B6CA00A06082A811CCF5501822D
A14403420004D7DE65FC282BC5CDC3CCEEF07762CEB6528245371ADE3344700F14C2049D345219DF
2D3377E3B10B390A71782B961B9B291B269CBEF9677A13779CDC2D7A6F95
  1. 根据BER编码格式进行解析

因为数据域是构造类型,因此需要再解析,以此往复,最终解析格式如下:

30 类型域 构造类型 
81 93 长度域 0x93 = 147
    02	通用类型	INTEGER
    01	长度为1
    00	数据域	
    30	构造类型
    13	长度19
            06	通用类型	对象标识符
            07	长度 7
            2A8648CE3D0201	数据域
            06	通用类型	对象标识符
            08	长度 8
            2A811CCF5501822D	数据域
    04	通用类型	八进制字符串
    79	长度 121
    
            30	构造类型
            77	长度 119
            
                  02	通用类型	INTEGER
                  01	长度 1
                  01	数据域
                  
                  04	通用类型	八进制字符串
                  20	长度 32
                  B4936A77871CD86B7386147F529EF7FC1E5A3D76A29CD5424F79BD3F3D3D9B6C	数据域
                A0	构造类型
                0A	长度 10
                    06	通用类型	对象标识符
                    08	长度 8
                    2A811CCF5501822D	数据域
                A1	构造类型
                44	长度 68
                    03	通用类型	BIT STRING
                    42	长度 66
                    0004D7DE65FC282BC5CDC3CCEEF07762CEB6528245371ADE3344700F14C2049D345219DF2D3377E3B10B390A71782B961B9B291B269CBEF9677A13779CDC2D7A6F95	数据域
  1. 根据各BER编码格式解析各数据域(建议自己手动计算一遍),得到:
---0    //指定私钥信息(PrivateKeyInfo)结构中的版本号
------1.2.840.10045.2.1 // 公钥对象标识符
-------1.2.156.10179.1.301  //SM2 算法对象标识符
-------1        //椭圆曲线(Elliptic Curve,简称 EC)私钥结构的版本号
-------B4936A77871CD86B7386147F529EF7FC1E5A3D76A29CD5424F79BD3F3D3D9B6C//私钥
----------1.2.156.10179.1.301//SM2 算法对象标识符
----------04D7DE65FC282BC5CDC3CCEEF07762CEB6528245371ADE3344700F14C2049D345219DF2D3377E3B10B390A71782B961B9B291B269CBEF9677A13779CDC2D7A6F95   //公钥,其中首字节04 并不是公钥信息,而是表示随后的数据是一个非压缩的点

至此,心中一阵舒畅。终于解决了心中的不快。还请注意,该pem私钥文件,并没有加密。所以能够解析出实际数据内容

总结

详细介绍了如何从.pem格式的私钥证书中提取公钥和私钥信息。.pem文件是私钥证书的常见格式,而der格式是.pem文件中数据的基本格式。文章通过介绍pem和der的关系、ASN.1、BER编码格式等基础知识,帮助读者理解如何解析.pem文件中的数据。

在这里插入图片描述
若我的内容对您有所帮助,还请关注我的公众号。不定期分享干活,剖析案例,也可以一起讨论分享。
我的宗旨:
踩完您工作中的所有坑并分享给您,让你的工作无bug,人生尽是坦途
在这里插入图片描述
在这里插入图片描述

标签:编码,字节,pem,PEM,-----,类型,长度,搞懂,解析
From: https://blog.csdn.net/xieyihua1994/article/details/140693421

相关文章

  • 程序设计:C++入门教程(速成) + 15道经典例题(附带例题解析)
    本文章以实用为主,若实在是不明白文字所表达的内容,无脑复制代码,自己动手运行一下,实验一下即可理解文章内容,放心,代码是全的,全选复制粘贴即可不废话,直接开整数据类型常用数据类型int:整数类型,用于表示整数值。例如:1,2,-3,0等。float:单精度浮点数类型,用于表示带有小数点的数......
  • 钢铁百科:舞钢产20号钢材质解析,20#钢板调质状态交货,20号钢力学性能
    20#钢板材质是一种优质的低碳碳素钢,具有良好的韧性、塑性和焊接性。以下是对其执行标准、化学成分、力学性能、交货状态、应用范围及常用规格的详细介绍。执行标准:对于厚度在3~60mm的20#钢板,执行标准为GB/T711-2008,其交货状态通常为热轧,也可根据需求进行正火、退火或高温......
  • 钢铁百科:15#钢材质解析,15号钢四切,NB二探保材质保性能
    一、15#钢执行标准:   -GB/T711-2017:这是目前关于15#钢板的主要执行标准,该标准确保了钢板的质量、生产流程和性能均达到国家规定的要求。二、15#钢化学成分:*碳(C):0.12~0.18%*硅(Si):0.17~0.37%*锰(Mn):0.35~0.65%*硫(S)和磷(P)的含量均不超过0.035%此外,还可能含有少量的铬(Cr)、......
  • C语言【面试】常用知识点总结之常用易错易混点解析
    第二部分:程序代码评价或者找错有符号整型和无符号整型混合运算时,有符号型自动转换成无符号型,运算的结果是无符号的。如果参与运算的数据类型不同,会自动转化为同一类再运算,这就是自动转换自动转换的规则如下:1.当参与运算的数据的类型不同时,编译系统会自动先将他们转换成......
  • 信息收集:网络空间测绘FOFA,查询语法最全使用方法(图文解析)
    前言经小绿书粉丝投稿,特意搜集了一些fofa的使用教程和一些高级用法什么是FOFA?官网描述:FOFA-网络空间资产搜索引擎是华顺信安推出的一款通过对全球网络对外开放服务的资产进行主动或被动方式探测、抓取、存储,分析整理不同种类的网络空间资产指纹信息(规则),并对符合规则的资产......
  • 【Git-驯化】一文搞懂git中代码回测reset详细使用方法
    【Git-驯化】一文搞懂git中代码回测reset详细使用方法 本次修炼方法请往下查看......
  • 错误 1 error LNK2019: 无法解析的外部符号 _MQTTClient_create,该符号在函数 "protect
    前言全局说明错误1errorLNK2019:无法解析的外部符号_MQTTClient_create,该符号在函数"protected:virtualint__thiscallCmfc_mqttclientpoweronoffDlg::OnInitDialog(void)"(?OnInitDialog@Cmfc_mqttclientpoweronoffDlg@@MAEHXZ)中被引用一、说明环境:Windows1......
  • Java编程指南:高级技巧解析 - Excel单元格样式的编程设置
    最新技术资源(建议收藏)https://www.grapecity.com.cn/resources/前言在Java开发中,处理Excel文件是一项常见的任务。在处理Excel文件时,经常需要对单元格进行样式设置,以满足特定的需求和美化要求,通过使用Java中的相关库和API,我们可以轻松地操作Excel文件并设置单元格的样式。在......
  • 上门维修安装派单系统啄木鸟平台小程序:服务产品类目设计与系统解析
    在现代生活中,上门维修安装服务已成为居民日常生活中不可或缺的一部分。为了提升用户体验与服务效率,开发一个高效、灵活的上门维修安装派单系统平台显得尤为重要。本平台小程序,如啄木鸟平台,精心设计了全面的服务产品类目体系,以满足多样化的维修安装需求。服务产品类目设计概览平......
  • 前端国际化原理解析
    <script>//1.定义msg值的数据源constmessages={en:{msg:'helloworld'},zh:{msg:'你好世界'}}//2.定义切换变量letlocale='en'//3.定义赋值函数functiont(key){returnmessage......