密码学基础之ASN.1编码

news2024/10/5 13:49:48

简介

  • ASN.1(Abstract Syntax Notation One),抽象语法标记。
  • ASN.1是一种国际标准的正式语言,由国际标准化组织(ISO)和国际电信联盟(ITU-T)共同制定,用于定义数据结构的抽象语法。它的设计目标是为了提供一种独立于特定计算机硬件、操作系统或编程语言的方式,来描述数据的结构和编码规则,以便在网络上传输和处理数据。
  • 那么为什么要熟悉ASN.1编码?因为在密码学中,像数字证书、公私钥、P7数字签名等信息都是ASN.1编码的数据。熟悉ASN.1编码才能更方便的去分析数据。

格式

  • <新类型的名字> ::=<类型描述>
    • <新类型的名字>: 一个以大写字母开头的标识符
    • <类型描述>: 基于内建类型或在其它地方定义的类型
    • 示例
      •   SM2Signature ::=SEQUENCE{
          						R INTEGER,
          						S INTEGER
          						}
        

DER编码

  • ASN.1的编码格式有很多种: BER、CER、DER、XER,密码学上大部分使用DER编码。

  • DER编码遵循TLV格式,即Type,Length,Value

  • Type

    通常为1个字节,创建类型如下:
    编码类型描述类别
    0x01BOOLEAN布尔类型,TRUE或FALSE基本类型
    0x02INTEGER用于表示整数值,可以是正数、负数或零
    0x03BIT_STRING位字符串,每个位可以独立设置为0或1
    0x04OCTET_STRING八进制字符串
    0x05NULL表示一个特殊的空值
    0x06OID用于唯一标识ASN.1定义的对象或类型
    0x0cUTF8StringUnicode字符的UTF-8编码字符串字符串类型
    0x30SEQUENCE包含一个或多个类型的有序字段系列构造类型
    0x31SET包含一个或多个类型的无序字段系列
  • Length

    • 为定长及不定长类型,一般为1-3字节,定长分为短格式和长格式。这里只介绍定长格式。
    • 如果value的值小于等于127个字节,那么Length占用一个字节,表示Value值的长度。
    • 如果value的值大于等于128个字节,则第一个字节的最高位会被设置为1,其余的7位用于表示后续字节中用来表示实际长度的字节数。之后的字节则按顺序组成实际的长度值。
    • 在这里插入图片描述
    • 如图,Value长度为52个字节,Length占用1个字节,值为52,表示的就是Value的长度。
    • Value的值为4934个字节时,Length占用了3个字节,第一个字节的最高位被置为1,其余7位表示Length还需要占用多少个字节,这里值为2,表示Length还需要占用2个字节,往后再取2个字节,值为4934个字节,表示Value的实际值为4934个字节。
  • Value: 存储实际的数据值,其格式和内容依据前面的Type和Length决定

类型详解

  • ASN.1数据在线解析网站
  • OID在线查询网站
  • 数据类型中,INTEGER、BIT STRING和OID这三种类型编码比较复杂,也比较难理解,会重点进行介绍。

BOOLEAN

  • 布尔值可以是 TRUE 或 FALSE
  • 在这里插入图片描述

INTEGER

  • 如果整数为正数,但高阶位设置为 1,则会将前导0x00添加到内容中,以指示数字不是负数。 例如,0x8F (10001111) 的高阶字节为 1。 因此,将前导零字节添加到内容,如下图所示。
  • 在这里插入图片描述
  • 解析一个SM2加密后的ASN.1编码的密文数据分析以下。
  • 在这里插入图片描述
  • 看下第一个整数,从第3个字节开始,02表示类型,20表示整数的值长度,为32个字节。从07开始到1D,就是实际的Value值。
  • 在这里插入图片描述
  • 再看第2个整数,02表示类型,21表示长度,为33个字节。然后是Value值,可以看到Value值的第一个字节是00,这是填充的数据,后面AB开始才是实际的Value值。为什么要填充00?因为整数值的最高位表示正负数,AB值的最高位为1,如果不填充00,就会把AB开始的Value值当作负数处理,因此最高位填充00,表示正数。

BIT STRING

  • BIT STRING类型是用来表示任意长度的二进制位序列,这种类型可以包含0个或多个比特,并且可以明确指定哪些比特位是重要的或者说是意义明确的,而其余未标记的比特位通常是填充的或应被忽略的。
  • 在这里插入图片描述
  • 如图所示,BIT STRING类型的V部分的第一个字节为数据填充标志,表示实际数据需要填充多少位。如果实际数据长度的位数不是8的整数倍,需要填充成8的整数倍,具体填充多少位,就在V的第一个字节中表示。如果实际数据长度的位数是8的整数倍,不需要填充,则V的第一个字节数据填充标志就为0x00。数据填充标志后面部分才是实际的数据值。
  • 在这里插入图片描述
  • 如上图所示,T为0x03,表示类型为 BIT_STRING。L为0x03,表示数据长度占3个字节。V的第一个字节为0x04,表示实际的值有四个未使用的位,需要填充,可以看到V的第三个字节的后四位填充了xxxx,填充的值是什么无所谓,但是这四位的值是不使用的,一般都是填充0。
  • 再分析以下一组Hex数据
    •   03 81 81 00 47 eb 99 5a df 9e 70 0d fb a7 31 32 c1 5f 5c 24 c2 e0 bf c6 24 af 15 66 0e b8 6a 2e ab 2b c4 97 1f e3 cb dc 63 a5 25 ec c7 b4 28 61 66 36 a1 31 1b bf dd d0 fc bf 17 94 90 1d e5 5e c7 11 5e c9 55 9f eb a3 3e 14 c7 99 a6 cb ba a1 46 0f 39 d4 44 c4 c8 4b 76 0e 20 5d 6d a9 34 9e d4 d5 87 42 eb 24 26 51 14 90 b4 0f 06 5e 52 88 32 7a 95 20 a0 fd f7 e5 7d 60 dd 72 68 9b f5 7b 05 8f 6d 1e
      
  • 第一个字节为0x03,表示类型为BIT_STRING。第二个字节为0x81,二进制为 10000001,可以看到最高位为1。回顾上文中Length的编码规则,如果Length的第一个字节最高位为1,则其他7位表示Length占用了几个字节,这里其他7位为1,表示Length占用了一个字节,往后再取一个字节,为0x81,这个表示的才是Value的实际长度,为129个字节。后面就是Value部分,第一个字节为0x00,表示数据部分不需要填充,0x00后面的内容就是实际的值。
  • 我们通过ASN.1数据在线解析网站 分析下这部分数据。
  • 在这里插入图片描述
  • 可以看到,Length表示的长度为 129个字节,但实际数据长度是1024位,也就是128个字节。说明Value部分的第一个字节只表示填充信息,不是实际的数据信息。
  • 那么有以下两组位串数据,我们尝试进行下ASN.1编码
    •   {1,1,0,1,0,1,0,1}
        {1,0,1,1,0,1,1,1,0,1,0,0,1}
      
    • 第一组数据进行编码,类型为 0x03,数据长度为1个字节,再加一个填充标识字节,Length为 0x02,数据长度为8位,不需要填充,则Value部分的第一个字节为0x00,第二个字节为实际的值 0xd5。则最终编码值为 030200d5。
    • 第二组数据进行编码,类型为 0x03,数据长度为2个字节,再加一个填充标识字节,Length为0x03,数据长度为13位,必须为8的倍数,因此填充3个字节,则Value部分的第一个字节填充标志为0x03。这里可以直接填充0,那么实际的值为1011011101001000,即为0xb748。最终编码值为 030303b748。
    • 分别解码看下
    • 在这里插入图片描述
    • 在这里插入图片描述

NULL

  • 长度为 0x00,且不带值字节
  • 在这里插入图片描述

OID

  • OID(OBJECT IDENTIFIER)对象标识符。

  • OID编码规则

    • 第一个字节编码是固定的,为OID数据的第1个数据乘以40再加上第2个数据。
    • 后面的其他数据,如果小于等于127,则直接进行编码。
    • 如果数据大于127,需要用多个字节表示。先将这个数据拆分为 x * 128 + y的形式,比如401 = 3 * 128 + 17的形式,然后第一个字节就为x,第二个字节为y。x为0x03,二进制为 00000011,但是x不能编码出401,需要和y一起编码才能表示401,因此需要将x的最高位替换为1,表示后面还有字节来编码401,替换后为10000011,编码为0x83,y为17,二进制为 00010001,x和y可以成功编码出401,后面没有其他数据了,y就不需要替换最高位,直接编码为 0x11,则401的最终编码为 0x83,0x11。
  • SM3WITHSM2的OID为 1.2.156.10197.1.501,尝试进行下编码

    • 请添加图片描述

    • 为了方便,这里用 a.b.c.d.e.f 代表 1.2.156.10197.1.501

    • 先编码1个字节。值为 1 * a + b = 1 * 40 + 2 = 42,编码为0x2A。

    • 再编码第2个和第3个字节。c = 156 = 1 * 128 + 28,则第二个字节1,二进制为 00000001,最高位需要替换为1,表示后续还有其他字节,为 10000001,编码为0x81,第三个字节为28,二进制为00011100,后续没有其他字节,直接编码为0x1C。

    • 接着编码第4个和第5个字节。d = 10197 = 79 * 128 + 85,则四个字节为79,二进制为01001111,后面还有其他字节,第一位替换为1,为11001111,编码为0xCF,第五个字节为85,二进制为01010101,后续没有其他字节,编码为0x55。

    • 第6个字节编码。e = 1,直接编码为0x01

    • 第7个和第8个字节编码。f = 501 = 3 * 128 + 117,第7个字节为3,二进制为 00000011,后面还有其他字节,最高位替换为1,为 10000011,编码为0x83,第8个字节为117,二进制为01110101,编码为0x75。

    • 最终编码值为 2A 81 1C CF 55 01 83 75,加上T和L,则OID最终编码为 06 08 2A 81 1C CF 55 01 83 75

    • 在这里插入图片描述

  • 国密算法的OID含义

    对象标识符OID对象标识符定义类别
    1.2国际标准化组织成员表示通用对象标识符
    1.2.156中国
    1.2.156.197国家密码管理局
    1.2.156.10197国家密码行业标准化技术委员会
    1.2.156.10197.1密码算法
    1.2.156.10197.1.100分组密码算法分组密码算法对象标识符
    1.2.156.10197.1.102SM1分组密码算法
    1.2.156.10197.1.103SSF33分组密码算法
    1.2.156.10197.1.104SM4分组密码算法
    1.2.156.10197.1.200序列密码算法序列密码算法对象标识符
    1.2.156.10197.1.201祖冲之序列密码算法
    1.2.156.10197.1.300公钥密码算法公钥密码算法对象标识符
    1.2.156.10197.1.301SM2椭圆曲线公钥密码算法
    1.2.156.10197.1.301.1SM2-1数字签名算法
    1.2.156.10197.1.301.2SM2-2密钥交换协议
    1.2.156.10197.1.301.3SM2-3公钥加密算法
    1.2.156.10197.1.302SM9标识密码算法
    1.2.156.10197.1.302.1SM9-1数字签名算法
    1.2.156.10197.1.302.2SM9-2密钥交换协议
    1.2.156.10197.1.302.3SM9-3密钥封装机制和公钥加密算法
    1.2.156.10197.1.400杂凑算法杂凑算法对象标识符
    1.2.156.10197.1.401SM3密码杂凑算法
    1.2.156.10197.1.401.1SM3密码杂凑算法, 无密钥使用
    1.2.156.10197.1.401.2SM3密码杂凑算法, 有密钥使用
    1.2.156.10197.1.500组合运算机制组合运算算法对象标识符
    1.2.156.10197.1.501基于SM2算法和SM3算法的签名
    1.2.156.10197.1.504基于RSA算法和SM3算法的签名
    1.2.156.10197.4.3CA代码CA代码对象标识符
    1.2.156.10197.6标准体系标准体系对象标识符
    1.2.156.10197.6.1基础类
    1.2.156.10197.6.1.1算法类
    1.2.156.10197.6.1.1.1《祖冲之序列密码算法》
    1.2.156.10197.6.1.1.2《SM4分组密码算法》
    1.2.156.10197.6.1.1.3《SM2椭圆曲线公钥密码算法》
    1.2.156.10197.6.1.1.4《SM3密码杂凑算法》
    1.2.156.10197.6.1.2标识类
    1.2.156.10197.6.1.2.1《密码应用标识规范》
    1.2.156.10197.6.1.3工作模式
    1.2.156.10197.6.1.4安全机制
    1.2.156.10197.6.1.4.1《SM2密码使用规范》
    1.2.156.10197.6.1.4.2《SM2加密签名消息语法规范》
    1.2.156.10197.6.2设备类
    1.2.156.10197.6.3服务类
    1.2.156.10197.6.4基础设施
    1.2.156.10197.6.5检测类
    1.2.156.10197.6.5.1《随机性检测规范》
    1.2.156.10197.6.6管理类

SEQUENCE

  • 可以把 SEQUENCE 类型看成C语言中的结构体
  • 解析一张x509格式的数字证书看下
    • 在这里插入图片描述
  • 可以看到 SEQUENCE 中包含了其他 SEQUENCE 类型或者基本类型。
  • SEQUENCE 没有特殊的编码规则,就是按照标准 TLV格式进行编码。

SET

  • SET 也可以看成是C语言中的结构体,与 SEQUENCE 不同的是,SET是有序的。
  • 同样解析一个x509格式的数字证书
    • 在这里插入图片描述
  • 可以看到subject部分CN、ST、L、O、OU、CN的类型都为SET,说明必须按顺序进行排列。

参考

  • ASN.1 类型的 DER 编码

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

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

相关文章

Javaweb-初学

1.利用springboot开发一个web应用 简要流程&#xff0c;如下图 2.如何创建一个springboot的项目&#xff0c;下面两张图片是重点关注 第一张图片记得和图片一样改一下路径 第二张就是勾一个选项 3.第一个简单的springboot应用的开发 根据如下步骤进行操作 首先顶部要标识Res…

运算符重载之日期类的实现

接上一篇文章&#xff0c;废话不多说&#xff0c;直接上代码 Date.h #pragma once #include<iostream> using namespace std; #include<assert.h>class Date {//友元函数声明friend ostream& operator<<(ostream& out, const Date& d);friend …

在高并发场景下,怎样避免 PostgreSQL 的死锁问题?

文章目录 &#xff08;一&#xff09;不当的事务设计&#xff08;二&#xff09;不正确的锁使用&#xff08;三&#xff09;并发操作冲突&#xff08;一&#xff09;优化事务设计&#xff08;二&#xff09;正确使用锁&#xff08;三&#xff09;调整数据库参数&#xff08;四&…

解决error Error: certificate has expired问题

安装环境遇到下面问题&#xff1a; 产生原因&#xff1a;可能是开了服务器代理访问导致ssl安全证书失效 解决办法&#xff1a; 在终端输入以下命令&#xff1a; yarn config set "strict-ssl" false -g

简单科普-GPT到底是什么?

1.ChatGPT ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;是OpenAI研发的一款聊天机器人程序 &#xff0c;于2022年11月30日发布 。ChatGPT是人工智能技术驱动的自然语言处理工具&#xff0c;它能够基于在预训练阶段所见…

MathType7.4.4破解版下载支持win版+Mac版

MathType的安装过程非常简单&#xff0c;只需要从官网下载安装文件&#xff0c;然后按照提示进行安装即可。在安装过程中&#xff0c;软件会提示你选择是否安装MathPage插件。如果你经常需要在网页上编辑和发布公式&#xff0c;建议选择安装这个插件。 界面简洁直观 打开MathTy…

sheng的学习笔记-AI-密度聚类

AI目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 需要学习的前置知识&#xff1a;聚类&#xff0c;可参考&#xff1a;sheng的学习笔记-AI-聚类(Clustering)-CSDN博客 什么是密度聚类 密度聚类亦称“基于密度的聚类”(density-based clustering)&#xff0c;此类算法假设…

Python逻辑控制语句 之 判断语句--if、if else 和逻辑运算符结合

逻辑运算符&#xff1a; and or not 1.案例一 需求&#xff1a; 1. 获取⽤户输⼊的⽤户名和密码 2. 判断⽤户名是 admin 并且密码是 123456 时, 在控制台输出: 登录成功! 3. 否则在控制台输出: 登录信息错误! # 需求&#xff1a; # 1. 获取用户输入的用户名和密码 # 2. 判断…

探索 Electron:将 Web 技术带入桌面应用

Electron是一个开源的桌面应用程序开发框架&#xff0c;它允许开发者使用Web技术&#xff08;如 HTML、CSS 和 JavaScript&#xff09;构建跨平台的桌面应用程序&#xff0c;它的出现极大地简化了桌面应用程序的开发流程&#xff0c;让更多的开发者能够利用已有的 Web 开发技能…

微服务-网关Gateway

个人对于网关路由的理解&#xff1a; 网关就相当于是一个项目里面的保安&#xff0c;主要作用就是做一个限制项。&#xff08;zuul和gateway两个不同的网关&#xff09; 在路由中进行配置过滤器 过滤器工厂&#xff1a;对请求或响应进行加工 其中filters&#xff1a;过滤器配置…

Typescript 【实用教程】(2024最新版)含类型声明,类型断言,函数,接口,泛型等

简介 TypeScript 是 JavaScript 的超集&#xff0c;是 JavaScript&#xff08;弱类型语言&#xff09; 的强类型版本。 拥有类型机制文件后缀 .tsTypescript type ES6TypeScript 和 JavaScript 的关系类似 less 和 css 的关系TypeScript对 JavaScript 添加了一些扩展&#x…

《人人都是产品经理》:项目一图流

《人人都是产品经理》&#xff1a;项目一图流 项目一图流 项目一图流

[NSSCTF]-Reverse:[SWPUCTF 2021 新生赛]easyapp(安卓逆向,异或)

无壳 把后缀名改为zip&#xff0c;找到apk 查看jadx 这里调用了MainActivity的lambda$onCreate$0$MainActivity&#xff0c;然后又调用了Encoder进行异或。 exp&#xff1a; result棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌 key987654321 flag for i in range(len(result)):flagchr(…

深入 SSH:解锁本地转发、远程转发和动态转发的潜力

文章目录 前言一、解锁内部服务&#xff1a;SSH 本地转发1.1 什么是 SSH 本地转发1.2 本地转发应用场景 二、打开外部访问大门&#xff1a;SSH 远程转发2.1 什么是 SSH 远程转发2.2 远程转发应用场景 三、动态转发&#xff1a;SSH 让你拥有自己的 VPN3.1 什么是 SSH 动态转发3.…

【工程实践】大模型推理指定GPU

前言 使用大模型进行推理&#xff0c;一般是在docker容器中&#xff0c;记录推理过程中遇到的问题。 问题描述 在使用docker容器时&#xff0c;在docker run时&#xff0c;如果使用的是--gpus all&#xff0c;这样在进入容器之后&#xff0c;会使用全部的GPU&#xff0c;如下图…

【算法专题--链表】两数相加 -- 高频面试题(图文详解,小白一看就懂!!)

目录 一、前言 二、题目描述 三、解题方法 ⭐双指针 -- 模拟进位 (使用哨兵位头节点) &#x1f95d; 什么是哨兵位头节点&#xff1f; &#x1f347;思路解析 &#x1f34d;案例图解 四、总结与提炼 五、共勉 一、前言 两数相加 这道题&#xff0c;可以说是--…

如何将Hive表的分区字段插入PG表对应的时间戳字段?

文章目录 1、背景描述2、场景分析 1、背景描述 数据仓库的建设通常是为业务和决策服务的。在数仓开发的应用层阶段&#xff0c;BI可以直接从主题层/业务层取数&#xff0c;而前端需要根据具体的作图需求通过后端查询数据库 作图的指标需要根据主题层/业务层做查询计算&#xf…

基于C语言的Jacobi迭代和Gauss-Seidel迭代的方程组求解实现

文章目录 Jacobi迭代方法介绍Gauss-Seidel迭代方法介绍具体代码实现示例题目实现效果 Jacobi迭代方法介绍 Jacobi迭代法是一种简单的迭代求解方法&#xff0c;适用于严格对角占优矩阵。其基本思想是利用当前迭代步的已知解来更新下一个迭代步的解。在C语言实现中&#xff0c;我…

Textual Learning2 -- 使用时的小问题

1、出现的问题&#xff1a; 在vscode里面直接运行函数会显示报错&#xff1a; 我尝试在vscode中含textual库的环境下运行&#xff0c;但仍然报错 2、解决方案&#xff1a; 在命令行中运行&#xff1a; 首先按winR&#xff0c;输入cmd打开命令行 或在已经安装的conda环境&a…

【JVM-01】引言

【JVM-01】引言 1. 什么是JVM&#xff1f;2. JDK、JRE、JVM比较3.常用的JVM有那些4.学习路线 1. 什么是JVM&#xff1f; JVM即 Java Virtual Machine(Java虚拟机)&#xff0c;是Java程序运行的环境(Java 二进制字节码运行环境)。 好处&#xff1a; 一次编写&#xff0c;到处…