ASN.1语言规范介绍

ASN.1介绍

X.509证书常用的编码方式有DER格式和PEM格式。证书是一个对象的话,那么需要一个描述这个对象的语言。ASN.1就是这样的一个语言规范。而DER是ASN.1编码的一种方式。如果要解析DER编码文件,就需要了解ASN.1语言规范的编解码。

ASN.1(Abstract Syntax Notation One)是OSI(Open Source Interconnection)使用的描述对象的语言规范。OSI是X.200中定义的。而ASN.1是X.208中描述的。

下面是一个ASN.1的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
Foo DEFINITIONS ::= BEGIN

Question ::= SEQUENCE {
id INTEGER,
question IA5String
}

Answer ::= SEQUENCE {
id INTEGER,
answer BOOLEAN
}

END

以一个证书分析ASN.1语法

以下是一个PEM格式的证书。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
-----BEGIN CERTIFICATE-----

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

-----END CERTIFICATE-----

对这个证书进行解析的方法是用一个在线的工具 http://lapo.it/asn1js/

可以把上面base64编码的证书复制到网站解码之后,可以看到类似如下的结果。

cert-parse

ASN.1的编码基本上遵循的是type+length+value的方式。

ASN.1的数据tag大概有以下几种,

type tagNumber
Boolean 0x01
Integer 0x02
BitString 0x03
OctetString 0x04
Null 0x05
ObjectIdentifier 0x06
Enumerated 0x0a
UTF8String 0x0c
Sequence 0x10
Set 0x11
PrintableString 0x13
IA5String 0x16
UTCTime 0x17
UnicodeString 0x1e

那么具体看一下以上ca证书的前四个字节是什么含义。

1
30 82 05 C1
  1. 首先看是什么type。第一个字节0x30描述了type信息。tagClass = 0x30 >> 6 = 0 ,表示universal isConstructed = 0x30 & 0x20 = True,对于sequence基本都是true, tagNumber = 0x30 & 0x1F = 0x10 ,因此对应的Sequence

  2. 接下来计算长度。 第二个字节为0x82, 分两种情况,判断表达式,byte & 0x7F == byte 如果为true就是小于127。否则就是大于127。

  • 长度是小于127(short form) 那么该该字节就是length,之后就是value的内容。
  • 长度大于127(long form), byte & 0x7F 表示length的编码长度。

对于以上的例子,0x82是long form 因为

1
( 0x82 == (0x82 & 0x7F) = False

那么表示长度的字节数量是

1
0x82 & 0x7F = 0x2

因此’0x82’之后的两个字节’0x05’和’0xC1’组成长度。

1
0x05C1 = 1473 

两个字节表示value的长度1473。

因此,

1
30 82 05 C1

这个头四个字节的含义是,这个是Sequence类型, 长度是1473,这四节之后的1473个字节就是Sequence类型的值。