ASN.1 – Abstract Syntax Notation dot one,抽象记法1。数字1被ISO加在ASN的后边,是为了保持ASN的开放性,可以让以后功能更加强大的ASN被命名为ASN.2等,但至今也没有出现。
描述了一种对数据进行表示、编码、传输和解码的数据格式。它提供了一整套正规的格式用于描述对象的结构,而不管语言上如何执行及这些数据的具体指代,也不用去管到底是什么样的应用程序。
其中:
是一个以大写字母开头的标识符;
是基于内建类型或在其它地方定义的类型。
其中:
是以小写字母开头的标识符;
可以是一个类型的名字,也可以是类型描述;
值描述>是基于整数、字符串、标识符的组合。
微软的CryptAPI很强大,证书的各种格式都可以识别,比如纯BASE64编码的、标准PEM格式的、非标识PEM格式的(不是64字节换行、没有头尾等)、二进制格式的
描述了如何将ASN.1 类型的值编码成字节串的方法。BER的语法传输格式一直是TLV三元组<Type, Length,Value>
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
(1)定长方式
length=30 表示为1E(16进制),30长度域为 0001 1110 没有超过127;
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结尾。这种方式使得可以在编码没有完全结束的情况下,可以先发送部分消息给对方。
最高位为0:0BBBBBBB
最高位为1:00000000|1BBBBBBB
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
TRUE的编码: 01 01 FF FALSE 的编码: 01 01 00
位串{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.
举例: 30331 = 1* 128^2 + 108 * 128 + 123 分割成7位数字(0x80)后为{1,108,123}
设置最高位后变成{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.
如: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