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编码的证书复制到网站解码之后,可以看到类似如下的结果。
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证书的前四个字节是什么含义。
首先看是什么type。第一个字节0x30
描述了type信息。tagClass = 0x30 >> 6 = 0 ,表示universal isConstructed = 0x30 & 0x20 = True
,对于sequence
基本都是true,
tagNumber = 0x30 & 0x1F = 0x10
,因此对应的Sequence
接下来计算长度。
第二个字节为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
|
那么表示长度的字节数量是
因此’0x82’之后的两个字节’0x05’和’0xC1’组成长度。
两个字节表示value的长度1473。
因此,
这个头四个字节的含义是,这个是Sequence
类型,
长度是1473,这四节之后的1473个字节就是Sequence
类型的值。