ASN.1编码方式详解

摘要:
与大多数计算机语言一样,ASN。1不转换空格、制表符、换行符和注释。ASN中。1有多种编码格式:BER、CER、DER、XER。它可以被编码成XML格式,而不仅仅是普通的二进制流。BER、CER和DER是ASN最常用的三种编码格式。1.CER、DER、CRT与PEM的关系。所有X.509都是DER代码。DER指ASN的编码规则。1 der证书文件通常是二进制文件。PEM通常指文件的后缀。内容以BASE64编码,并具有特定的头尾格式。二进制文件不应命名为pem。

ASN

ASN.1 – Abstract Syntax Notation dot one,抽象记法1。数字1被ISO加在ASN的后边,是为了保持ASN的开放性,可以让以后功能更加强大的ASN被命名为ASN.2等,但至今也没有出现。

描述了一种对数据进行表示、编码、传输和解码的数据格式。它提供了一整套正规的格式用于描述对象的结构,而不管语言上如何执行及这些数据的具体指代,也不用去管到底是什么样的应用程序。

基本语法规则

  • 在ASN.1中,符号的定义没有先后次序:只要能够找到该符号的定义即可,而不必关心在使用它之前是否被定义过。
  • 所有的标识符、参考、关键字都要以一个字母开头,后接字母(大、小写都可以)、数字或者连字符“-”。不能出现下划线“_”。不能以连字符“-”结尾,不能出现两个连字符(注释格式)。
  • 关键字一般都是全部大写的,除了一些字符串类型(如PrintableString,UTF8String,等。因为这些都是由原类型OCTET STRING衍生出来的)。
  • 在标识符中,只有类型和模块名字是以大写字母开头的,其它标识符都是以小写字母开头的。
  • 带小数点的小数形式不能在ASN.1中直接使用,在ASN.1中实数实际定义为三个整数:尾数、基数和指数
  • 注释以两个连字符“--”开始,结束于行的结尾或者该行中另一个双连字符。
  • 如同大多数计算机语言,ASN.1不对空格、制表符、换行符和注释做翻译。但是在定义符号(或者分配符号Assignment)“::=”中不能有分隔符,否则不能正确处理。

类型定义与类型

  1. <新类型的名字> ::= <类型描述>

​ 其中:

<新类型的名字>是一个以大写字母开头的标识符;

​ <类型描述>是基于内建类型或在其它地方定义的类型。

  1. 值定义:<新的值的名字> <该值的类型> ::= <值描述>

其中:

<新的值的名字>是以小写字母开头的标识符;

<该值的类型>可以是一个类型的名字,也可以是类型描述;

值描述>是基于整数、字符串、标识符的组合。

  • ASN.1的编码格式有很多种: BER、CER、DER、XER,可以编码成XML格式,不仅仅是常用的二进制流。BER、CER、DER,是ASN.1的三种最常用的编码格式

CER、DER、CRT、PEM的关系

  • 所有X.509都是DER编码,DER是指ASN.1的编码规则,.der证书文件一般是二进制文件。

  • CER可用于PKCS#7证书(p7b)的编码,但一般是指证书的文件后缀,.cer证书可以是纯BASE64文件或二进制文件。

  • PEM通常也是指文件的后缀,为内容使用BASE64编码且带头带尾的特定格式,二进制的文件不应该命名为pem。

  • CRT是微软的证书后缀名,和.CER是一回事。

微软的CryptAPI很强大,证书的各种格式都可以识别,比如纯BASE64编码的、标准PEM格式的、非标识PEM格式的(不是64字节换行、没有头尾等)、二进制格式的

BER编码

描述了如何将ASN.1 类型的值编码成字节串的方法。BER的语法传输格式一直是TLV三元组<Type, Length,Value>

  • tag(标志域): 指明数据类型,占用一个字节常见的类型有
BER_TYPE_BOOLEAN	0x01
BER_TYPE_INTEGER	0x02
BER_TYPE_BIT_STRING	0x03
BER_TYPE_OCTET_STRING	0x04
BER_TYPE_NULL	0x05
BER_TYPE_OID	0x06
BER_TYPE_SEQUENCE	0x30
BER_TYPE_SNMP_SET	0xA3
  • 长度域(length):指明值域的长度,长度不等,一般为一到三个字节。其格式可分为短格式(后面的值域长度<=127),长格式.

(1)定长方式

短格式

length=30 表示为1E(16进制),30长度域为 0001 1110 没有超过127;

  • 长格式 :表示方法为1(bit)K(7bit)K个八位长度(K Byte)

长格式

length = 169 转换为 81 A9(169长度超过127,长度域为1000 0001 1010 1001;169是后8位的值,前8位的第一个1表示这是一个长格式的表示方法,前8位的后7位表示后面有多少个字节表示针对的长度000 0001后面有一个字节表示真正的长度 1010 1001是表示长度为169)

​ length=1500=>82 05 DC(1000 0010 0000 0101 1101 1100,先看第一个字节,表示长格式,后面有2 个字节表示长度,这两个字节是0000 0101 1101 1100 表示1500)

(2).不定长方式

Length所在八位组固定编码为0x80,但在Value编码结束后以两个0x00结尾。这种方式使得可以在编码没有完全结束的情况下,可以先发送部分消息给对方。

Length所在八位组固定编码为0x80,但在Value编码结束后以两个0x00结尾。这种方式使得可以在编码没有完全结束的情况下,可以先发送部分消息给对方。

不定长

  • 值域(value)

  • 整型Integer的编码 integer::=0x02 length{byte} (表示重复),最高位代表符号位,去掉多余的0。对于正数,如果最高比特位为0则直接编码;如果为1,则在最高比特位之前增加一个全0的八位组。

    • 最高位为0:0BBBBBBB

    • 最高位为1:00000000|1BBBBBBB

  1. 例: 对于负数,先取绝对值进行编码,再取反,最后加1
1500=>02 02 05 DC 
40000=>02 03 00 9C 40
-129=>129=>0000 0000 1000 0001->1111 1111 0111 1110 ->(加1)->FF 7F 最终为02 02 FF 7F
  • 布尔值的编码由1个字节组成。FALSE为00; TRUE为FF。

    • TRUE的编码: 01 01 FF
    • FALSE 的编码: 01 01 00
  • 字符串类型的编码 string::=0x04 length{byte}* 例如:04 06 70 75 62 6c 69 63表示字符串public

  • 位串(BITSTRING)类型 :编码规则:位串的第一位放到第一个负载字节的第8位;位串的第二位放到第一个负载字节的第7位; 依此类推.填充满第一个负载字节,就继续填充第二个负载字节.如果最后一个负载字节未被填充满,空的位用0来填充, 0的个数存放到头部用来表示填充数据的那个字节里.

位串{1,0,0,0,1,1,1,0,1,0,0,1}
开始填充负载字节.第一个字节填充后为10001110= 0x8E; 第 二个字节填充后为10010000 = 0x90, 低位4个0为填充的空位.则,负载为2个字节加上表示填充0个数的一个字节0x04总共3个字节.则完整的编码为:0x03 03 04 8E 90.

  • 空类型的编码 null::=0x05 0x00

  • objectID::=0x06 length {subidentifier}*

  • 首两个ID被合并为一个字节X*40+Y

  • 每个字首先被分割为最少数量的没有头零数字的7位数字.这些数字以big-endian格式进行组织,并且一个接一个地组合成字节.

举例: 30331 = 1* 128^2 + 108 * 128 + 123 分割成7位数字(0x80)后为{1,108,123}
  • 除了编码的最后一个字节外,其他所有字节的最高位(位8)都为1.
设置最高位后变成{129,236,123}.如果该字只有一个7位数字,那么最高为0 
MD5 OID的编码:
1. 将1.2.840.113549.2.5转换成字数组 {42, 840, 113549, 2, 5}.
2.然后将每个字分割为带有最高位的7位数字,{{0x2A},{0x86,0x48},{0x86,0xF7,0x0D},{0x02},{0x05}}
3. 最后完整的编码为 0x06 08 2A 86 48 86 F7 0D 02 05.
  • sequence组合类型的编码 sequence::=0x30 length{asndata}*

如:30 05 02 01 10 05 00表示一个sequence结构,内含两个成员,其中一个为整型16,另一个为空类型(NULL)。

例:考虑如下序列


User ::== SEQUENCE{
ID INTEGER, 
Active BOOLEAN
}

当取值为{32,TRUE}时,编码为 0x30 06 02 01 20 01 01 FF 在ASN.1文档里,使用空格来表示编码的属性. 


0x30 06
02 01 20
01 01 FF

免责声明:文章转载自《ASN.1编码方式详解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇nohup命令及其输出文件基于python+Testlink+Jenkins实现的接口自动化测试框架V3.0下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

随便看看

14款优秀的JavaScript调试工具大盘点

官方网站:http://www.jshint.com/4.Grunt Grunt是一个基于任务的命令行构建工具,适用于JavaScript项目。Venkman旨在为Mozilla提供一个基于浏览器的强大JavaScript调试环境。官方网站:http://www.my-debugbar.com/wiki/CompanionJS/HomePage10.Simp...

MySQL 字段类型占用空间

MySQL支持多种列类型:数值类型、日期/时间类型和字符串(字符)类型。)1或2个字节,取决于枚举值的个数SET(‘value1’,’value2’,…)1、2、3、4或者8个字节,取决于set成员的数目上表的M只是为了说明占用空间大小,在实际创建表中char、varchar,20指的是字符而不是字节;那么字符和字节的转换要看字符集,utf-8下,1字符=3...

转:(WIN)S04-CH01 PCIE XDMA开发环境搭建以及环路测试

XDMAIP使用部分教程分LINUX篇和WINDOWS篇两个部分。通过实战,面向应用,提供给大家XILINXFPGAPCIE应用解决方案。本教程以MK7160FA作为样机测试。这是一款高性价比的FPGA开发板。而M_AXI_LITE挂载的BRAM是需要进行BAR空间操作,所以地址设置为0x80000000...

如何快速把ps序列图层建立帧动画?

工具ps1。将序列帧图片加载到ps新建-˃脚本-˃将文件加载到堆栈2中。创建序列帧动画窗口-˃时间线-˃时间线面板的右上菜单-˃从层3创建帧。移除多余的透明画布选择所有层-˃图像-˃剪辑-˃基于透明度4。将图层保存到图片文件-˃脚本-˃将图层保存为文件隐藏白色背景5。导出序列框架文件-˃自动-˃联系人表6存储为png...

ios 苹果和百度地图的相关使用

同时由于苹果使用的是高德,不会像谷歌地图一样在国内乌龟一样的访问速度,确实做一些地图相关的东西,非常有吸引力。只是实现了显示一个百度地图的view。百度地图使用的是Objective-C++,这意味这必须要有一个.mm文件。...

mac下vscode插件位置

1、 位置:Mac:User/(您的用户名)/vscode/extensions II下vscode插件的存储位置。搜索步骤:以我的mac为例,打开查找器,单击远程CD,单击转到上面的文件夹,单击macintosh HD,单击用户(或用户),单击mymac,单击。vscode(.vscode是一个隐藏文件。如果默认情况下不显示,请按住ctrl+shift+....