ASN.1笔记——标准编码规则BER - Netsharp - 博客园

九月 05, 2024 [网络与安全] #obsidian #协议与标准

ASN.1笔记——标准编码规则BER - Netsharp - 博客园

1. 基本规则

BER(BasicEncoding Rules)是ASN.1中最早定义的编码规则,其他编码规则是在BER的基础上添加新的规则构成。

1.1 Tag

Tag是一个或若干个八位组 第一个八位组高二位(第七、六位)指明Tag的类型,有四种取值:

第五位指明编码类型

1.1.1 Universal Tag类型

a. TagValue值为0-30

Tagvalue值是基本类型的Tag的值,例如INTEGER的Tag值是2,SEQUENCE型类Tag值是16,下表为ASN.1中定义的UNIVERSAL类Tag

Tag类型
0BER保留
1BOOLEAN
2INTEGER
3BIT STRING
4OCTET STRING
5NULL
6OBJECT IDENTIFIER
7ObjectDescripion
8EXTERNAL,INSTANCE OF
9REAL
10ENUMERATED
11EMBEDDED PDV
12UFT8String
13RELATIVE-OID
14保留
15保留
16SEQUENCE,SEQUENCE OF
17SET,SET OF
18NumericString
19PrintableString
20TeletexString,T61String
21VideotexString
22IA5String
23UTCTime
24GeneralizedTime
25GraphicString
26VisibleString,ISO646String
27GeneralString
28UniversalString
29CHARACTER STRING
30BMPString
31保留
b. TagValue > 30时

当TagValue大于30时,多个八位组中编码,第一个八位组后五位全部为1,其余的八位组最高位为1表示后续还有,为0表示Tag结束。

1.1.2 APPLICATION Tag类型

1.1.3 context-specific Tag类型

1.1.4 PRIVATE Tag类型

1.2 Length

BER编码中Length表示Value部分所占八位组的个数,有两大类:定长方式(DefiniteForm)和不定长方式(IndefiniteForm)

1.2.1 定长方式

定长方式中,按长度是否超过一个八位,又分为短、长两种形式:

1.2.2 不定长方式

Length所在八位组固定编码为0x80,但在Value编码结束后以两个0x00结尾。这种方式使得可以在编码没有完全结束的情况下,可以先发送部分消息给对方。

2. 各类型的编码

以UNIVERSAL Tag和短型Value为例,讨论各种类型的BER编码,重点关注Value部分。

2.1 BOOLEAN

只能以primitive方式编码

2.2 NULL

只能以primitive方式编码,且只有一个值:

2.3 INTEGER

只能以primitive方式编码。

2.3.1 正数

如果最高比特位为0则直接编码;如果为1,则在最高比特位之前增加一个全0的八位组。

2.3.2 负数

对于负数,先取绝对值,再取反,最后加1。

2.4 ENUMERATED

按照整数值的规则编码。

2.5 REAL

2.6 BIT STRING

可以primitive方式编码或者constructed方式编码。

2.6.1 Primitive方式

例如'1011011101011'B的编码 V中第一个八位取值0-7,表示在这个V后面补的0的个数 如果BITSTRING的值为空,则编码时,长度为1,补充的八位组为全0。

2.6.2 constructed方式

'1011011101011'B的编码 L的最高位是1,说明是不定长方式编码,V中嵌套两个TLV,以Primitive方式表示这个值的高八位和低八位,最后以两个全为0的八位结尾

2.7 OCTET STRING

与BITSTRING类似,但是不需要增加表征补充位个数的八位组。

2.8 OBJECT IDENTIFIER

只能以primitive方式编码。编码时,第一个八位组采用公式:first_arc* 40+second_arc。如果一个数大于127,就采用多个8位表示,最高位用1表示后续还有octet,用0表示后续没有。 例:对{isomember-body f(250) type-org(1) ft(16) asn1-book(9)}的编码为 注意对250的编码方式,1×128+122。

2.10 字符串和日期

和OCTETSTRING编码类似,只是Tag不同。

2.11 SEQUENCE

只能用constructed形式。对每个成员均以TLV方式编码,且顺序要与定义的一致。 v SEQUENCE { age INTEGER, single BOOLEAN } ::={age 24, single TRUE }的编码为: 注意BOOLEAN类型,非0表示真。 忽略扩展符'...',对扩展的内容则按顺序编码。

2.12 SET

与SEQUENCE类似,但是成员顺序有发送者决定。

2.13 SEQUENCEOF

SEQUENCEOf的Tag与SEQUENCE相同,编码规则也相同。

2.14 SETOF

与SEQUENCEOf类似。

2.15 CHOICE

严格说CHOICE类型在编码中并不存在,只是在描述中体现一种关系。编码时,是按照具体被选择的成员编码规则编码的。 例如amousCHOICE { name VisibleString, nobody NULL } ::= name:"Perec" 的编码为: Tag为26,上选定成员的类型的tag。 如果CHOICE类型显式(EXPLICIT)指定了Tag,那么该Tag应当以constructed方式编码。 忽略扩展符'...',对扩展的内容则按顺序编码。

2.16 Tag对编码的影响

(1).如果Tag是隐式的,或者在模块定义中声明了IMPLICITTAGS或者AUTOMATICTAGS,则只有关键字IMPLICIT左侧的Tag才会被编码。如: v [1]IMPLICIT INTEGER ::= -38的编码为: (2).如果一个类型的Tag是显式(EXPLICIT)的(或者在模块定义中声明了EXPLICITTAGS),则要以constructed方式编码三元组系列。 如v[APPLICATION 0] EXPLICIT INTEGER ::= 38的编码为:

2.17 子类型约束

子类型约束是在BER编码规则之后被引入ASN.1的,在编码规则中不能体现约束。

2.18 EXTERNAL

该类型不推荐使用,略。

2.19 INSTANCEOF

定义为:

vINSTANCE OF TYPE-IDENTIFIER ::=
{
  type-id{iso member-body f(250) type-org(1) ft(16) asn1-book(9)
  chapter18(5)integer- type(0)},
  valueINTEGER:5
}

的编码应当和如下一个SEQUENCE类型的值类似:

{
  direct-reference{iso member-body f(250) type-org(1) ft(16) asn1-book(9)
  chapter18(5)integer-type(0)},
  encodingsingle-ASN1-type:INTEGER:5
}

编码为: 为什么valueINTEGER:5的编码采用constructed方式,处层TLV的Tag为上下文类型,值为0?

2.20 EMBEDDEDPDV

EMBEDDEDPDV的编码和其等效的SEQUENCE结构编码类似。其嵌入部分的编码,应该是遵循identification成员指定的规则。

2.21 CHARACTERSTRING

CHARACTERSTRING的编码和其等效的SEQUENCE结构编码类似。其嵌入字符串部分的编码,应该是遵循identification成员指定的规则。

2.22 InformationObjects and Object Sets

信息对象和对象集合永远都不编码。如前所述,传递他们所包含信息的途径是在值定义或者类型定义中引用他们。这样的结果,不是在编码中出现了这些信息,而是ASN.1编译器在生成编解码器时,会按照这些信息生成相应的约束表。

2.23 ValueSet

值集合的编码按照对应类型的编码规则进行。

3. BER编码规则的属性

  1. BER编码规则是机器无关
  2. BER的传输语法是十分冗长。T和L很多情况下都是可以省略,但是这种冗余信息能很好的保藏抽象语法结构。
  3. BER传输语法能容易升级而且向上兼容。如每个类型都可以用CHOICE来代替

参考:https://blog.csdn.net/sever2012/article/details/7698297