IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> RSA加密中PEM、DER的编解码问题 -> 正文阅读

[网络协议]RSA加密中PEM、DER的编解码问题

1 前言

最近在玩CTF,还没入门,做题的时候遇到一道RSA的题,给了一个pubkey.pem文件和一个flag.enc文件。之前对于rsa的认识停留在ssh的时候生成公钥和私钥文件,但是文件里面具体内容没有关注过,所以打开pubkey.pem文件后不知道怎么处理。

看了网上都是直接用openssl工具直接解,但是这对我理解无益,因此想深入了解一下。bing一下之后知道.pem文件是PEM编码的文件,PEM实际上就是把DER编码的文件的二进制内容用base64编码一下,然后加上-----BEGIN label-----这样的头和-----END label-----这样的尾,中间则是DER文件的Base64编码。

在PEM转DER和DER解码过程中遇到一些问题,部分问题查了很多博客都没解释清楚,研究了很久。现将其整理至此,供大家参考。

2 PEM与DER转换

在写本篇博客的时候突然发现了 这篇博客讲得很详细,记录一下。

2.1 PEM转DER格式

先将 PEM 文件里面首尾的 “----BEGIN xxx----” 和 “----END xxx----” 两行去掉,再将内容合并为一行(去掉换行符),最后将内容进行 Base64 解码,最后结果就是 DER 格式。

2.2 DER转PEM格式

先将 DER 二进制内容进行 Base64 编码,再按每行 64 个字节进行切分,最后在切分后的内容前后加上 “----BEGIN xxx----” 和 “----END xxx----”。

3 DER解码

DER(Distinguished Encoding Rules,可辨别编码规则)是BER(Basic Encoding Rules,基本编码规则)的一个子集。前段时间在研究SNMP协议,BER再熟悉不过了,所以对DER解码一下子来了劲。

对pubkey.pem进行base64解码转换为DER编码后得到

303C300D06092A864886F70D0101010500032B003028022100C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD0203010001

3.1 初步解码

按BER编码规则进行解码,得到的结果是

DER编码                              ; 解码结果(字节数为16进制)
30 3C                                ; SEQUENCE (3C Bytes)
|  30 0D                             ; SEQUENCE (D Bytes)
|  |  |  06 09                       ; OBJECT_ID (9 Bytes)
|  |  |  2A 86 48 86 F7 0D 01 01 01  ; 1.2.840.113549.1.1.1(OID编码规则请自行搜索) 
|  |  05 00                          ; NULL (0 Bytes)
|  03 2B                             ; BIT_STRING (2B Bytes)
|     00
|     30 28                          ; SEQUENCE (28 Bytes)
|        02 21                       ; INTEGER (21 Bytes)
|        |  00
|        |  C2 63 6A E5 C3 D8 E4 3F  FB 97 AB 09 02 8F 1A AC
|        |  6C 0B F6 CD 3D 70 EB CA  28 1B FF E9 7F BE 30 DD
|        02 03                       ; INTEGER (3 Bytes)
|           01 00 01

查一下这个OID(1.2.840.113549.1.1.1),结果如下图所示,可以看到这个OID其实就是表明这是一个RSAES-PKCS1-v1_5加密机制。
OID查询结果
那另外两个整数(00 C2 63 6A E5 C3 D8 E4 3F FB 97 AB 09 02 8F 1A AC 6C 0B F6 CD 3D 70 EB CA 28 1B FF E9 7F BE 30 DD01 00 01)是什么呢?
这就涉及到PKCS的规范了。

3.2 DER文件结构

PKCS已经发布了15个标准,从PKCS#1到PKCS#15,想具体了解可以看对应的RFC。查了相关的RFC,发现这篇博客总结得不错,借鉴了一下。
PKCS#1规定的RSA公钥文件格式为

-----BEGIN RSA PUBLIC KEY-----
BASE64 ENCODED DATA
-----END RSA PUBLIC KEY-----

其base64编码数据解码对应的DER编码解码后的格式为

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

由于 RSA 并非专门在 X509 和 SSL/TLS 中使用,因此 PKCS#8 中提供了一种更通用的密钥格式用以标识公钥的类型并包含相关数据。
PKCS#8规定的公钥文件格式为

-----BEGIN PUBLIC KEY-----
BASE64 ENCODED DATA
-----END PUBLIC KEY-----

其base64编码数据解码对应的DER编码解码后的格式为

PublicKeyInfo ::= SEQUENCE {
  algorithm       AlgorithmIdentifier,
  PublicKey       BIT STRING
}

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

3.3 解码

至此,可以根据RSA公钥文件来确定DER编码解码后的格式了。3.1中的解码结果为

DER编码                              ; 解码结果(字节数为16进制)
30 3C                                ; SEQUENCE (3C Bytes)
|  30 0D                             ; SEQUENCE (D Bytes)
|  |  |  06 09                       ; OBJECT_ID (9 Bytes)
|  |  |  2A 86 48 86 F7 0D 01 01 01  ; 1.2.840.113549.1.1.1(algorithm) 
|  |  05 00                          ; NULL (0 Bytes, parameters)
|  03 2B                             ; BIT_STRING (2B Bytes, PublicKey)
|     00
|     30 28                          ; SEQUENCE (28 Bytes)
|        02 21                       ; INTEGER (21 Bytes, modulus, n)
|        |  00
|        |  C2 63 6A E5 C3 D8 E4 3F  FB 97 AB 09 02 8F 1A AC
|        |  6C 0B F6 CD 3D 70 EB CA  28 1B FF E9 7F BE 30 DD
|        02 03                       ; INTEGER (3 Bytes, publicExponent, e)
|           01 00 01

关于BIT_STRING和modulus部分数据以0x00开头的说明
上面的解码过程中可以看到BIT_STRING和modulus的content字段都是以0x00开头(highlight部分),看了网上很多博客都没有解释清楚,甚至还有说错了误导人的。

03 2B 00 30 28 02 21 00 C2 63 6A E5 C3 D8 E4 3F FB 97 AB 09 02 8F 1A AC 6C 0B F6 CD 3D 70 EB CA 28 1B FF E9 7F BE 30 DD 02 03 01 00 01

本着求知的精神,我去看了一下标准X.690 : Information technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)。关于这两个0x00,标准里写得非常清楚。下面给大家解释一下。

  • 第一个0x00
    标准中8.6.2.2原话是

The initial octet shall encode, as an unsigned binary integer with bit 1 as the least significant bit, the number of
unused bits in the final subsequent octet. The number shall be in the range zero to seven.

意思是BIT_STRING的content字段第一个字节需要指明这个bit string最后补了几个零(规定bit string按8位一组,最后一组不到8位则在末尾补齐0),也就是说,这个字节取值范围为0~7。因为后面都是整数,所以不需要补0,因此BIT_STRING的content字段第一个字节为0x00。

  • 第二个0x00
    标准中8.3.3原话是

The contents octets shall be a two’s complement binary number equal to the integer value, and consisting of bits 8
to 1 of the first octet, followed by bits 8 to 1 of the second octet, followed by bits 8 to 1 of each octet in turn up to and including
the last octet of the contents octets.

也就是说,整数用二进制补码表示。modulus值为C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD,这在RSA算法中其实是一个无符号整数,但是如果以二进制补码来看这是一个负数,因此需要在前面加上0x00以保证这是一个正整数。

Ref

1.https://blog.csdn.net/ttyy1112/article/details/107064407
2.https://tls.mbed.org/kb/cryptography/asn1-key-structures-in-der-and-pem
3.https://www.itu.int/rec/T-REC-X.690-202102-I/en
4.https://blog.csdn.net/fengshenyun/article/details/124596279

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-05-10 12:14:59  更:2022-05-10 12:15:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:38:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码