ASN.1筆記——語法規則與類型概述


一.簡介

ASN.1(Abstract Syntax Notation dotone)抽象語法標記定義抽象數據類型形式的標準,是用於描述數據表示、傳輸和編碼的記法。

ASN.1只包含信息結構,不處理具體業務數據,它不是一個編程語言。

ASN.1沒有限定編碼方法,各種ASN.1編碼規則提供了由ASN.1描述其抽象句法的數據的值的傳送語法(具體表達)。

常見的編碼規則有:基本編碼規則(BER)、規範編碼規則(CER,CanonicalEncoding Rules)、唯一編碼規則(DER,DistinguishedEncoding Rules)、壓縮編碼規則(PER,PackedEncoding Rules)和XML編碼規則(XER,XMLEncoding Rules)。這些編碼規則描述瞭如何將定義在ASN.1中的值譯成適合傳輸的電碼。


ASN.1在OSI的ISO8824/ITU X.208(說明語法)和ISO8825/ITU X.209(說明基本編碼規則)規範。

幾個概念:

(1)實際語法

指諸如C、ObjectiveCaml等這樣實際編程語言;

(2)抽象語法(AbstractSyntax)

指協議採用ASN.1規範描述的描述文本。描繪了與任何表示數據的編碼技術無關的通用數據結構。抽象語法使得人們能夠定義數據類型,並指明這些類型的值。抽象語法只描述數據的結構形式,與具體的編碼格式無關,同時也不涉及這些數據結構在計算機內如何存放。

(3)傳輸語法(TransferSyntax)

指表示層交換數據的表示方法,是實際通訊系統間的碼流。當數據在兩個表示層實體之間傳輸時,這些數據的實際比特模式表示方法就是傳送語法。

(4)編碼

指將抽象語言法轉換成實際通訊系統間比特流;

(5)編碼規則

將抽象語言法轉換成實際通訊系統間比特流所遵循的語法規則;


.相關背景知識

1.爲了順利完成應用者的通訊,需使用以下概念:

(1)抽象語法:定義了數據的常用結構(包括不同的數據類型),並且建立了和應用層對話所用的構架。

(2)實際語法:本地的,並且定義本地系統的數據表示方法。

(3)傳輸語法:定義兩個系統間的表示層間交換數據的表示方法。

(4)編碼規則:提供從本地實際語法到傳輸語法和其相反操作的方法。(從抽象語法到傳輸語法,由ASN.1編譯器按照編解碼規則實現)

2.應用層Application Layer

應用層向表示層發送數據時,同時告知表示層自己的ASN.1名字(即對象標識符),ASN.1名字標記了一個ASN.1語法——用以解釋數據中各字段的含義。通過參考ASN.1定義,表示可以得知數據單元的類型和長度,以及傳輸時應當採用的編碼方法。

3.表示層Presentation Layer

兩個系統在傳輸數據前需要協商共用的編碼方式,事實上編碼方式在應用層發出的數據中已經確定,應用數據中包含抽象語法/傳輸語法的組合關係,告訴表示層數據的結構、含義以及傳輸語法規則。表示層參考抽象語法,將應用數據轉換爲傳輸語法定義的比特流。

4.邊界對齊

同樣一條消息,在計算機內存中是以Byte爲單位存儲的,在鏈路上則是以bit爲單位傳送的。

如果一個信元的第一個bit也恰好是Byte流中某Byte的開始bit時,我們稱之爲開始於邊界對齊的;

如果信元的最後一個bit也恰好是Byte流中某Byte的最後一個bit時,則可以稱之爲結束於邊界對齊的。

對於不是結束於邊界對齊的情況,一般要進行補位。有兩種方式:

(1)對每個信元的結束立即進行補位,保證下一個信元是開始於邊界對齊的;

( 2)從信元結束的位置開始新的信元,到消息結束時再進行一次補位操作。(用於無線空口中)

5.大小端(BigEndian vs Little Endian)

(1).大端方式,也叫網絡序,從左往右,第一個8位表示高位,例如0X0102,用比特流表示是0000000100000010。

(2).小端方式,也叫主機序,與大端方式相反,數字0X0102用比特流表示則是0000001000000001,低8位在前,高8位在後。

Motorola的PPC系列、IP協議中使用大端方式;VAX計算機、Intel的x86系列中使用小端方式。


.ASN.1的基本語法規則

1.ASN.1使用巴科斯範式(BNF):

在雙引號中的字("word")代表着這些字符本身。而double_quote用來代表雙引號。

在雙引號外的字(有可能有下劃線)代表着語法部分。

尖括號(< > )內包含的爲必選項。

方括號([ ] )內包含的爲可選項。

大括號({ } )內包含的爲可重複0至無數次的項。

豎線(| )表示在其左右兩邊任選一項,相當於"OR"的意思。

::=是“被定義爲”的意思。

這是用BNF來定義的Java語言中的For語句的實例:

   FOR_STATEMENT::=

   "for""(" ( variable_declaration |

   (expression ";" ) | ";" )

   [expression ] ";"

   [expression ]

   ")"statement

2.在ASN.1中,符號的定義沒有先後次序:只要能夠找到該符號的定義即可。

3.所有的標識符、參考、關鍵字都要以一個字母開頭,後接字母(大、小寫都可以)、數字或者連字符“-”(但不能以連字符“-”結尾,也不能連續出現兩個連字符),不能出現下劃線“_”。

4.關鍵字一般都是全部大寫。

5.在標識符中,只有類型和模塊名字是以大寫字母開頭的,其它標識符都是以小寫字母開頭。

6.ASN.1中實數實際定義爲三個整數:尾數、基數和指數。沒有小數表示方式。

7.ASN.1不對空格、製表符、換行符和註釋做翻譯。但是在定義符號(或者分配符號Assignment)“::=”中不能有分隔符。


.ASN.1中的類型

類型是一個非空的值的集合,可以被編碼後傳輸。相比與高級語言中複雜的數據結構,ASN.1中的類型主要是爲了數據的傳輸。

1.ASN.1中的類型分爲基本類型(內建數據類型)和組合類型,組合類型由一個或多個基本類型構成。

基本類型

類型

含義

NULL

只包含一個值NULL,用於傳送一個報告或者作爲CHOICE類型中某些值

INTEGER

全部整數(包括正數和負數)

REAL

實數,表示浮點數

ENUMERATED

標識符的枚舉(實例狀態機的狀態

BITSTRING

比特串

OCTETSTRING

字節串

OBJECT IDENTIFIER,

RELATIVE-OID

一個實體的標識符,它在一個全世界範圍樹狀結構中註冊

EXTERNAL,EMBEDDED PDV

表示層上下文交換類型

…String(除了BITSTRING、OCTETSTRING外)

各種字符串,有NumericString、PrintableString、VisibleStirng、ISO64String、IA5String、TeletexStirng、T61String、VideotexString、GraphicString、GeneralString、UniversalString、BMPString和UTF8String

CHARACTERSTRING

允許爲字符串協商一個明確的字符表

UTCTime,GeneralizedTime

日期

組合類型

類型

含義

CHOICE

在類型中選擇(相當於C中的聯合)

SEQUENCE

由不同類型的值組成一個有序的結構(相當於C中的結構體)

SET

由不同類型的值組成一個無序的結構

SEQUENCEOF

由相同類型的值組成一個有序的結構(相當於C中的數組)

SETOF

由相同類型的值組成一個無序的結構


2.類型定義

<新類型的名字>::= <類型描述>

例:

Married ::= BOOLEAN

Age ::= INTEGER

Picture ::= BIT STRING

Form ::= SEQUENCE

{

name PrintableString,

age Age,

married Married,

marriage-certificate PictureOPTIONAL

}

Married類型是一個基本類型BOOLEAN,Form類型是一組基本類型的有序序列

注意:在SEQUENCE和SET等(好像應該是所有組合類型的)定義中,最後一個成員結尾沒有逗號“,”。

爲了接收方能正確解碼,發送方爲每個值的類型加一個數,稱爲tag,在描述中以“[]”標識。缺省情況下,編碼器使用universaltag。在給合類型中,爲了明確各個成員,有必要指明每個成員的Tag:

Coordinates ::= SET

{

x [1] INTEGER, //這證明好像也可以用類來直接聲明變量

y [2]INTEGER,

z [3]INTEGER OPTIONAL

}

Tag會在傳輸規則使用到,用於在比特流中指明數據的具體類型。

爲了準確描述一個類型,我們需要對值的集合進行一定的限制。這用到子類型約束,在類型之後用圓括號進行標識。

如:

Lottery-number::= INTERGER(1..49)表示1-49任一一個值

Lottery-draw ::=SEQUENCESIZE(6) OF Lottery-number指定了該SEQUENCE類型由6Lottery-number類型有序組成。

Upper-case-words::= IA5String (FROM(“A”..”Z”))表示按ASCIIA-Z中任一一個,IA5StringASCII字符串類型

爲了方便在新的版本中往現有類型中添加新成員,可用“…”來標記可能以後是其它類型的地方:

Type ::= SEQUENCE

{

component1 INTERGER,

component2 BOOLEAN,

}

以後新的版本中,描述可能爲:

Type ::= SEQUENCE

{

component1 INTERGER,

component2 BOOLEAN,

,

[[component3REAL]], -- version 2

}

注意:新加入的類型成員要嵌套在“[[]]”,--version 2指定新版本號


3.值定義

<新的值的名字><該值的類型> ::=<值描述>

其中:

<新的值的名字>是以小寫字母開頭的標識符

<該值的類型>可以是一個類型的名字可以是類型描述

<值描述>是基於整數、字符串、標識符的組合

如:

counter Lottery-number ::= 45

sextuple Lottery-draw ::= { 7, 12, 23, 31, 33, 41 }


4.信息對象類和信息對象

<信息對象類>::= CLASS <類描述>

WITHSYNTAX <信息描述>

用於表達比註釋更爲正式的一些信息


5.模塊定義

<模塊名字> DEFINITIONS <缺省Tag>::=

BEGIN

EXPORTS <導出描述>

IMPORTS <導入描述>

<模塊體描述>

END

一般協議由一個或者多個模塊組成模塊用來收集數據結構定義

模塊名字必須以大寫字母開頭。模塊能以一種“全局指針”(UniversalPointer)的方式來引用,稱爲對象標識符(ObjectIdentifier),用花括號標識在名字之後。

如:

Module2 { isomember-body(2) f(250) type-org(1) ft(16)

asn1-book(9)chapter5(0) module2(1) }

DEFINITIONS AUTOMATICTAGS ::=

BEGIN

EXPORTS Type2;

IMPORTS Type1, valueFROM Module1 {iso member-body(2)

f(250) type-org(1)ft(16) asn1-book(9) chapter5(0) module1(0)};

Type2 ::= SEQUENCE OFChoice

Choice ::= CHOICE

{

a INTEGER (0..value),

b Type1

}

END

(1).AUTOMATICTAGS是指缺省Tag,說明不關注模塊的Tag

(2).IMPORTS聲明在其它模塊定義但在本模塊會用到的類型或者值。

EXPORT聲明在本模塊之外可以訪問的類型或者值。

IMPORTS的語法爲:

IMPORTS <名字>,value FROM <其它模塊的ObjectIdentifier >;

EXPORTS的語法爲:

EXPORTS<名字>;

(3).對象標識符(OBJECTIDENTIFIER,OID)類型用層次的形式來表示標準規範。標識符樹通過一個點分的十進制符號來定義,這個符號以組織,子部分然後是標準的類型和各自的子標識符開始.

例如:MD5OID1.2.840.113549.2.5表示爲"iso(1)member-body (2) US (840) rsadsi(113549) digestAlgorithm (2) md5 (5)",所以當解碼程序看到這個OID,就知道是MD5散列。

OID在公鑰算法標準中很流行,它指出證書綁定了哪種散列算法。

OID在傳輸時編碼規則:

  • 前兩部分如果定義爲x.y,那麼它們將合成一個字40*x+ y,其餘部分單獨作爲一個字節進行編碼。

  • 每個字首先被分割爲最少數量的沒有頭零數字的7位數字.這些數字以big-endian格式進行組織,並且一個接一個地組合成字節.除了編碼的最後一個字節外,其他所有字節的最高位(8)都爲1

MD5OID的編碼:

<1>.1.2.840.113549.2.5轉換成字數組{42,840, 113549, 2, 5}

<2>.然後將每個字分割爲帶有最高位的7位數字,{{0x},{0x86,0x48},{0x86,0xF7,0x0D},{0x02},{0x05}}

<3>.最後完整的編碼爲0x0608 86 48 7 0D 02 05。 


6.模塊和分配(Assignment)

(1).定義一個新類型

TypeReference ::=CHOICE

{

integer INTEGER,

boolean BOOLEAN

}

(2).給類型賦值

ASN.1中給類型賦的值不會被編碼(ASN.1語法只是一種語法規則用來描述業務數據,而不會被當成業務數據),這種值常用DEFAULT上下界或者信息對象中

value-referenceTypeReference ::= integer:12

如果兩個類型語法上完全一樣的,則這兩種類型的值可以相互賦值。如:

Pair::= SEQUENCE

{

x INTEGER,

y INTEGER

}

Couple::= SEQUENCE

{

x INTEGER,

y INTEGER

}

pairPair ::= {x 5, y 13}

coupleCouple ::= pair

(3).值集合

在語義上,一個值集合相當於一個添加約束後的類型。如:

PrimeNumbers INTEGER ::= {2 | 3 | 5 | 7 | 11 | 13}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章