- asn.1 编码和工具(多找)
- BER和DER编码 (openssl应用举例)
asn.1 编码和工具
在ASN.1编码方面,有许多工具可供使用,例如OpenSSL、GnuTLS、Wireshark等。这些工具可以用于生成ASN.1描述的数据结构、将ASN.1数据结构编码成二进制格式、解码ASN.1数据结构等。此外,还有一些专门用于ASN.1编码的工具,例如asn1c、asn1scc等,它们可以将ASN.1描述的数据结构编译成C、C++等语言的代码,以便在程序中使用。
windows:
- ASN1 VIEW
https://bbs.csdn.net/topics/396899413 - ASN.1 Editor
https://blog.csdn.net/henter/article/details/103057538
linux:
- asn1c:
https://blog.csdn.net/weixin_42508903/article/details/116942796 - openssl:
https://blog.csdn.net/fengbingchun/article/details/106487696
开发工具:
http://en.asnlab.com/downloads.html
BER和DER编码
BER基本编码规则(Basic Encoding Rule)
把 ASN.1 表示的抽象类型值编码为字节串,这种字节串的结构为类型—长度—值,简称 TLV(Type-Length-Value)。
其中 Type 和 Length 都是1个字节,而且值部分还可以递归地再编码为 TLV 结构,这样就具有了表达复杂结构的能力。
编码的第一个字节表示 ASN.1 类型或用户定义的类型,前2位用于区分 4 种标签,第 3 位用于区分简单类型和构造类型,其余 5 位表示标签的值。
例:
十进制数 256 的编码,把这个数用二进制表示就是 00000001 00000000,十六进制为 01 00 需要 2 字节。int 类型是通用标签 UNIVERSAL,属于简单类型,标签号为 2 号,根据上述的表格就可以写出 Type 字段:00000010。由于这个数用二进制表示需要 2 字节,所以 L 字段值为 00000010,十六进制表示为 02。
Type | Length | Value |
---|---|---|
00 0 00010 | 00000010 | 00000001 00000000 |
02 | 02 | 01 00 |
字节串 ACE 的编码,由于字节串总是占用整数个字节,因而不必说明未占用的比特数。没有说明值的位都认为是 0,故最后一个字节写为 E0,可见字节串类型也遵循靠左存放的原则。
octet str 类型是通用标签 UNIVERSAL,属于简单类型,标签号为 4 号,根据上述的表格就可以写出 Type 字段:00000100。
Type | Length | Value |
---|---|---|
00 0 00100 | 00000010 | 10101100 11100000 |
04 | 02 | AC E0 |
DER
DER(可分辨编码规则)是BER的受限变体,用于为ASN.1描述的数据结构生成明确的传输语法。与CER一样,DER 编码是有效的 BER 编码。DER 与 BER 相同,但删除了一个发送者的选项。
DER 是 BER 的一个子集,提供了一种编码 ASN.1 值的方法。DER 适用于需要唯一编码的情况,例如在密码学中,并确保需要数字签名的数据结构产生唯一的序列化表示。DER 可以被认为是BER的规范形式。例如,在 BER 中,布尔值 true 可以编码为 255 个非零字节值中的任何一个,而在 DER 中,有一种方法可以对布尔值 true 进行编码。
DER编码过程
以CN、学号、姓名为例
先查看三项的ASCII码
- AttributeType编码
AttributeType为OBJECT IDENTIFIER基本类型,编码规则采用基本类型定长模式。
对于标识串,采用低标识编码方式,只需1个字节。OBJECT IDENTIFIER的tag为0x06:class选择universal,则位8和位7为0,OBJECT IDENTIFIER为基本类型,则位6为0。因此,标识串=0x06。
对于长度串,采用短型编码方式,只需1个字节。
对于内容串,由3个字节组成。2.5.4.6编码为55 04 06,2.5.4.10编码为55 04 0A,2.5.4.3编码为55 04 03。
AttributeType | OID定义 | 标识串 | 长度串 | 内容串 |
---|---|---|---|---|
countryName | 2.5.4.6 | 06 | 03 | 55 04 06 |
organizationName | 2.5.4.10 | 06 | 03 | 55 04 0A |
commonName | 2.5.4.3 | 06 | 03 | 55 04 03 |
- AttributeValue编码
AttributeValue为PrintableString基本类型,编码规则采用基本类型定长模式。
对于标识串,采用低标识编码方式,只需1个字节。PrintableString的tag为0x13;class
选择universal,则位8和位7为0,OBJECT IDENTIFIER为基本类型,则位6为0。因此,标识串=0x13。
对于长度串,采用短型编码方式,只需1个字节。
对于内容串,由其ASCII码组成
RelativeDistinguishedName | 标识串 | 长度串 | 内容串 |
---|---|---|---|
CN | 13 | 02 | 43 4E |
20201318 | 13 | 08 | 32 30 32 30 31 33 31 38 |
Lixingxin | 13 | 09 | 4c 69 78 69 6e 67 78 69 6e |
- AttributeValueAssertion编码
AttributeValueAssertion为SEQUENCE结构类型,编码规则采用结构类型定长模式。
对于标识串,采用低标识编码方式,只需1个字节。SEQUENCE的tag为OxlO:class选择universal,则位8和位7为0,SEQUENCE为结构类型,则位6为1。因此,标识串0x30.
对于长度串,采用短型编码方式,只需1个字节。
对于内容串,由AttributeType和AttributeValue的DER编码值组成。
AttributeValueAssertion | 标识串 | 长度串 | 内容串 |
---|---|---|---|
countryName="CN" | 30 | 09 | 06 03 55 04 06 \ 13 02 \ 43 4E |
organizationName="20201318" | 30 | 0F | 06 03 55 04 0A \13 08 \32 30 32 30 31 33 31 38 |
commonName="Lixingxin" | 30 | 10 | 06 03 55 04 03 \ 13 09 \ 4c 69 78 69 6e 67 78 69 6e |
- RelativeDistinguishedName编码
RelativeDistinguishedName为SET OF结构类型,编码规则采用结构类型定长模式。
对于标识串,采用低标识编码方式,只需1个字节。SET OF的tag为0xl1;class选择universal,则位8和位7为0,SET OF为结构类型,则位6为1。因此,标识串=0x31。
对于长度串,采用短型编码方式,只需1个字节。
对于内容串,由AttributeValueAssertion的DER编码值组成。
AttributeValueAssertion | 标识串 | 长度串 | 内容串 |
---|---|---|---|
countryName="CN" | 31 | 0B | 30 09 \ 06 03 55 04 06 \ 13 02 \ 43 4E |
organizationName="20201318" | 31 | 11 | 30 0F \ 06 03 55 04 0A \ 13 08 \ 32 30 32 30 31 33 31 38 |
commonName="Lixingxin" | 31 | 12 | 30 10 \ 06 03 55 04 03 \ 13 09 \ 4c 69 78 69 6e 67 78 69 6e |
- RDNSequence编码
RDNSequence为SEQUENCE OF结构类型,编码规则采用结构类型定长模式。
对于标识串,采用低标识编码方式,只需1个字节。SEQUENCE OF的tag为0x10;class选择universal,则位8和位7为0,SEQUENCE OF为结构类型,则位6为1。因此,标识串=0x30。
对于长度串,采用短型编码方式,只需1个字节。
对于内容串,由3个RelativeDistinguishedName的DER编码值组成。
AttributeValueAssertion | 标识串 | 长度串 | 内容串 |
---|---|---|---|
countryName="CN" | 30 | 0D | 31 0B \30 09 \ 06 03 55 04 06 \ 13 02 \ 43 4E |
organizationName="20201318" | 30 | 13 | 31 11 \ 30 0F \ 06 03 55 04 0A \ 13 08 \ 32 30 32 30 31 33 31 38 |
commonName="Lixingxin" | 30 | 14 | 31 12 \ 30 10 \ 06 03 55 04 03 \ 13 09 \ 4c 69 78 69 6e 67 78 69 6e |
- Name编码
Name为CHOICE类型,其DER编码值与RDNSequence相同。
最终编码为:
CN:13
//13
30 34 //34(16)=52(10)
//52=13+19+20
31 0B
30 09
06 03 55 04 06
13 02
43 4E
20201318:
//19
31 11
30 0F
06 03 55 04 0A
13 08
32 30 32 30 31 33 31 38
Lixingxin:
//20
31 12
30 10
06 03 55 04 03
13 09
4c 69 78 69 6e 67 78 69 6e
用openssl中的ans1parse查看:
CN:
echo -n -e "\x31\x12\x30\x10\x06\x03\x55\x04\x03\x13\x09\x4c\x69\x78\x69\x6e\x67\x78\x69\x6e" >> 1.der
20201318:
echo -n -e "\x31\x11\x30\x0F\x06\x03\x55\x04\x0A\x13\x08\x32\x30\x32\x30\x31\x33\x31\x38" >> 1.der
Lixingxin:
echo -n -e "\x31\x12\x30\x10\x06\x03\x55\x04\x03\x13\x09\x4c\x69\x78\x69\x6e\x67\x78\x69\x6e" >> 1.der