X.690 ASN.1编码规则:BER、CER、DER初识

1. 简介

ASN.1(Abstract Syntax Notation One)是一个标准的接口描述语言(Interface description language/IDL),IDL是可以在跨平台中实现序列化和反序列化的数据结构。

ASN.1只定义了抽象语法,并没有限定编码规则。当前较为流行的编码规则有:Basic Encoding Rules(BER)、Canonical Encoding Rules(CER)、Distinguished Encoding Rules(DER)。本文是基于ITU-T X.690规范初步阅读形成的一个笔记。

1.1 BER、CER、DER差异

BER是ITU-T X.690给出的传输ASN.1数据结构的一套基础编码规则,因此它的规则较为宽松和灵活,在规则范围内,发送放可以自由选择。例如一个boolean类型的true值,只要该字节非0x00即可,因此发送放可以选择0x01表示true,也可以选择0x02表示true。

DER和CER在BER基础上进一步添加限制,形成一套比BER严格的编码规则,因此DER和CER是BER的一个子集。
在这里插入图片描述

BER/CER/DER编码都是典型的TLV格式:Type-Length-Value
在这里插入图片描述

基础的TLV结构包含如下三部分:

  • Type:Value标识符,标识Value类型
  • Length:Value长度
  • Value:数据内容
    TLV允许多层嵌套,如图所示,1级Value中,嵌套1个2级TLV,2级TLV中又嵌套1个TLV队列(包含2个TLV)

DER和CER一个显著的差异在于:DER的length长度必须是明确的,而CER可以通过end-of-contents octets来表明Value结束(end-of-contents octets详见章节2.1和2.1.4)。

2.BER

2.1 基础规则

BER编码也遵循TLV结构,如下:
在这里插入图片描述
a. identifier octets
b.length octets
c.contents octets
d.end-of-contents octets
end-of-contents octets只在length octets中要求展现时,才会展现。默认不进行展现。

2.1.1 identifier octets

identifier octets包含三个部分:Class、P/C、Tag number。针对不同的Tag number又分为2种情况:

2.1.1 .1 Tag number小于31(十进制)

当ag number小于31时,identifier octets长度为1个字节,格式如下:
在这里插入图片描述

  • Class:2个bit。包含4个值
    a. 00:Universal。最常用的类型。在ITU-T X.680里定义的tag number均属于此类型。详见Tag number处表格。
    b. 01:Application。
    c. 10:Context-specific。
    d. 11:Private。
  • P/C:1个bit。标记后续contents octets是一个基础值还是一个嵌套的TLV值。
    0:Primitive。后续contents octets为基础值
    1:Constructed。后续contents octets为嵌套的TLV。
  • Tag number:5个bit。最大值为0x1F,即十进制的31。

Type中字段规范表如下:

NameClassP/CDecimal Tag numberHexadecimal Tag number
End-of-Content(EOC)UniversalPrimitive00
BOOLEANUniversalPrimitive11
INTEGERUniversalPrimitive22
BIT STRINGUniversalBoth33
OCTET STRINGUniversalBoth44
NULLUniversalPrimitive55
OBJECT IDENTIFIERUniversalPrimitive66
Object DescriptorUniversalBoth77
EXTERNALUniversalConstructed88
REAL (float)UniversalPrimitive99
ENUMERATEDUniversalPrimitive10A
EMBEDDED PDVUniversalConstructed11B
UTF8StringUniversalBoth12C
RELATIVE-OIDUniversalPrimitive13D
TIMEUniversalPrimitive14E
ReservedUniversal/15F
SEQUENCE and SEQUENCE OFUniversalConstructed1610
SET and SET OFUniversalConstructed1711
NumericStringUniversalBoth1812
PrintableStringUniversalBoth1913
T61StringUniversalBoth2014
VideotexStringUniversalBoth2115
IA5StringUniversalBoth2216
UTCTimeUniversalBoth2317
GeneralizedTimeUniversalBoth2418
GraphicStringUniversalBoth2519
VisibleStringUniversalBoth261A
GeneralStringUniversalBoth271B
UniversalStringUniversalBoth281C
CHARACTER STRINGUniversalConstructed291D
BMPStringUniversalBoth301E
DATEUniversalPrimitive311F
TIME-OF-DAYUniversalPrimitive3220
DATE-TIMEUniversalPrimitive3321
DURATIONUniversalPrimitive3422
OID-IRIUniversalPrimitive3523
RELATIVE-OID-IRIUniversalPrimitive3624
2.1.1.2 Tag number大于31

当ag number大于等于31时,因1个字节的identifier octets只有5bit的tag number,无法表示31以上的值,此时需要identifier octets长度超过1个字节,identifier octets格式如下:
在这里插入图片描述

  • Class、P/C的值和Tag number小于31时无差异
  • 第一个字节的tag number字段(bit 1到bit 5)全部为二进制的1。后续字节的最高位bit8为标记位,若该位为0,则表明该字节为identifier octets最后1个字节,否则该位为1。Tag number由所有的Subsequent octet中bit7到bit1按照大端模式拼接而成。

2.1.2 length octets

length octets如下图所示
在这里插入图片描述
共存在4中场景:
1.Contents octets长度小于等于127字节:此时length octets长度为1个字节,bit 8为0,bit7~bit1存储Contents octets长度值。
2.length octets无需指明Contents octets长度:此时length octets长度为1个字节,bit 8为1,bit7~bit1全部为0。Contents octets结束后必须紧跟end-of-contents octets,用于表明Contents octets结束。
3.Contents octets长度大于127字节:此时length octets长度超过1个字节。bit 8为0,bit7~bit1表明后续还有几个字节。后续的字节值代表Contents octets的长度。例如Contents octets长度为290个字节,则length octets第1个字节值为0x82(bit8~bit1分别为10000010),第2个字节为0x01,第3个字节为0x22,最终的Contents octets长度为0x0122,即290个字节。
4.保留:此时length octets长度为1个字节,bit 8为1,bit7~bit1全部为1

总体上来说,发送者可以选择指定长度或不指定长度两种方式。是否指定长度,需遵守如下规则:
1.如果P/C是primitive,则必须在length octets中指定长度
2.若P/C是constructed且值是已知的,则两种方式都可以选择
3.若P/C是constructed且值不可知,则使用不指定长度的方式

2.1.3 contents octets

对数据值进行编码后保存在contents octets中,contents octets可以有0个、1个或多个字节组成。contents octets需要和tag number对应的Type类型匹配。

2.1.4 end-of-contents octets

当length octets为10000000,即0x80时,表明未指定contents octets长度。此时,当contents octets结束时,必须紧跟end-of-contents octets。end-of-contents octets为2个字节的0x00。

2.2 数据类型介绍

针对Contents octets的不同类型数据,本章节将介绍部分常见数据值。数据类型总览表如下:

NameClassP/CDecimal Tag numberHexadecimal Tag number
End-of-Content(EOC)UniversalPrimitive00
BOOLEANUniversalPrimitive11
INTEGERUniversalPrimitive22
BIT STRINGUniversalBoth33
OCTET STRINGUniversalBoth44
NULLUniversalPrimitive55
OBJECT IDENTIFIERUniversalPrimitive66
Object DescriptorUniversalBoth77
EXTERNALUniversalConstructed88
REAL (float)UniversalPrimitive99
ENUMERATEDUniversalPrimitive10A
EMBEDDED PDVUniversalConstructed11B
UTF8StringUniversalBoth12C
RELATIVE-OIDUniversalPrimitive13D
TIMEUniversalPrimitive14E
ReservedUniversal/15F
SEQUENCE and SEQUENCE OFUniversalConstructed1610
SET and SET OFUniversalConstructed1711
NumericStringUniversalBoth1812
PrintableStringUniversalBoth1913
T61StringUniversalBoth2014
VideotexStringUniversalBoth2115
IA5StringUniversalBoth2216
UTCTimeUniversalBoth2317
GeneralizedTimeUniversalBoth2418
GraphicStringUniversalBoth2519
VisibleStringUniversalBoth261A
GeneralStringUniversalBoth271B
UniversalStringUniversalBoth281C
CHARACTER STRINGUniversalConstructed291D
BMPStringUniversalBoth301E
DATEUniversalPrimitive311F
TIME-OF-DAYUniversalPrimitive3220
DATE-TIMEUniversalPrimitive3321
DURATIONUniversalPrimitive3422
OID-IRIUniversalPrimitive3523
RELATIVE-OID-IRIUniversalPrimitive3624

若需了解详细规则,请参考ITU-T X.680相关标准。

2.2.1 Boolean

Boolean的Contents octets只占用1个字节。当boolean值为FALSE,contents octets值为0x00。当boolean值为TRUE,contents octets值为非0x00,即范围在0x01到0xFF均合法,允许发送发自由定义。
示例
值为True的TLV结构

TLV
0x010x010xFF

2.2.2 INTEGER

integer类型的contents octets可以包含1个到多个字节。若contents octets包含多个字节时,第一个字节和第二个字节的bit8,不能全为1也不能全为0。contents octets应使用数值的补码。
示例
值为65537的TLV结构

TLV
0x020x030x01 0x00 0x01

2.2.3 NULL

null类型的不包含contents octets,length octets为0
示例

TL
0x050x00

2.2.4 UTF8String

UTF8编码的字符串
示例
字符串“tom”

TLV
0x0C0x030x74 0x6F 0x6D

2.2.5 SEQUENCE

标识contents octets是一个队列

示例
SEQUENCE {name UTF8String, ok BOOLEAN}对应的值为{name “tom”,ok TRUE}

TLV
0x300x080x0C 0x03 0x74 0x6F 0x6D 0x01 0x01 0xFF

在这里插入图片描述

3.CER和DER

CER和DER在BER基础上,进一步添加限制规则。

3.1 CER特有限制规则

1.如果tag number是constructed的,则Length octets应不指定长度(值为0x80)
2.bitstring/octetstring和restricted character string的contents cotets长度不超过1000个字节时,使用primitive编码。若超过10000个字节,应使用Constructed编码,每个string段长度为1000个字节且使用primitive,最后一个string段至少1个字节但不能超过1000个字节。(按标准翻译,没太理解)
3.set类型排序规则。

3.2 DER特有限制规则

1.length octets必须指明长度,且使用最小的字节数进行编码。
2.对于bitstring、octetstring、restricted character string类型,P/C不使用constructed。
3.set类型排序规则。

3.3 CER和DER公用规则

1.Boolean类型的TRUE值必须为0xFF
2.bitstring的最后一个字节里,未使用的bit需置0
3.当满足 ITU-T X.680 | ISO/IEC 8824-1, 22.7中内容时,在编码前,需移出尾部的所有0
等等(具体请查询X.690规范,此处未做深入研究)

4.总结

因公私钥、证书等均采用ASN.1进行编码,为更深入了解公私钥和证书信息,首先需要了解ASN.1和DER等规范。通过阅读ITU-T X.690规范,可以有效的初步掌握此类基础信息。若需深入了解不同数据的编码细节,需结合X.680,X.690等规范,深入阅读。

X.690规范的核心是TLV的数据结构。在TLV中,基于V的不同类型,产生了不同的T,L则用于表示V的长度,总体上形成一套完善的编码规范。

  • 31
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值