国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
asn.1介紹(來自網(wǎng)上)
userphoto

2010.07.16

關注
 
來自:
 
 

在UMTS中使用到了PER和BER編碼,其中25331消息,也就是RRC消息使用的PER編碼,而補充業(yè)務部分則使用BER編碼。

轉自:http://blog.csdn.net/ysr1980/archive/2009/04/13/4068218.aspx

1.什么是ASN.1(抽象語法記法一)?

        ASN.1是ITU-T的一個標準集,它用來編碼及表示通用數(shù)據(jù)類型,這些數(shù)據(jù)類型有可打印串值,八位位組串值,位串值,整數(shù)值以及用可移值方式組合而成的其他類型序列值.簡單的說,ASN.1指定了以何種方式對非平凡的數(shù)據(jù)類型進行編碼,以便其他任何平臺及第三方工具都能夠解釋其內(nèi)容.比如,字母a在一些平臺以ASCII編碼為十進制數(shù)值97,而在其他非ASCII平臺上,可能會是另外的編碼.而ASN.1指定了一種編碼方式,在任何平臺上,字母a的編碼都是統(tǒng)一的.

2.ASN.1語法.

        ASN.1語法遵循傳統(tǒng)的巴科斯范式BNF風格.最基本的表達式如: Name ::= type . 表示為定義某個名稱為Name的元素,它的類型為type. 例如: MyName ::= IA5String . 表示為定義了一個名為MyName的元素或變量,其類型為ASN.1類型IA5String (類似于ASCII字符串).

2.1 ASN.1顯式值(Explict Value).

  有些時候,我們需要定義一種ASN.1類型,它的子集元素包含預定義值. Name ::= type (Explict Value) .  顯式值(Explict Value).必須是ASN.1類型允許選擇的值,而且也必須是元素所允許的值.例: MyName ::= IA5String (Tom) 表示MyName是字符串Tom的IA5String編碼. 又例如: MyName ::= IA5String(Tom|Joe) 表示字符串的值既可以是Tom, 也可以是Joe.

        這種語法的使用是為了擴展確定的解碼器.例:

        PublicKey ::= SEQUENCE {

            KeyType       BOOLEAN(0),

            Modulus        INTEGER,

            PubExponent INTEGER

        }

        PrivateKey ::= SEQUENCE {

            KeyType       BOOLEAN(1)

            Modulus         INTEGER,

            PubExponent  INTEGER,

            PrivateExponent INTEGER

          }

2.2 ASN.1容器(container)

        容器是值一個包含了其他相同或者不同類型元素的數(shù)據(jù)類型(例如序列值SEQUENCE或集合值SET類型).目的是為了組合一些復雜的數(shù)據(jù)類型集.ASN.1規(guī)范定義了4種容器類型:序列,單一序列(SEQUENCE OF),集合和單一集合(SET OF).雖然它們意義不同,但是語法是一樣的.

        Name ::= Container {Name Type [ Name Type...]}   方括號中的內(nèi)容和容器的元素個數(shù)都是可選項.還可以進行嵌套定義.

例:

  UserRecord ::= SEQUENCE {

           Name   SEQUENCE {

               First IA5String,

               Last  IA5String

            },

           DoB     UTCTIME

        }

將其粗略的翻譯成C語言中的結構如下:

  struct UserRecord {

           struct Name {

             char *First,

             char *Last

           };

          time_t DoB;

        }

將其粗略的翻譯成Object Pascal語言中的記錄如下(Object Pascal不支持嵌套記錄):

       Type

            Name = record

              First : String;

              Last  : String;

            end;

            UserRecord = record

              aName : Name;

              DoB    : DateTime;

            end;

2.3ASN.1修改器

        ASN.1定義了各種修改器,如可選(OPTIONAL),默認(DEFAULT),和選擇(CHOICE). 他們可以改變表達式的聲明.典型地用于定義一種要求編碼靈活,而定義又不繁瑣的類型.

       <1>.可選(OPTIONAL)。顧名思義,其表示改變一個元素以便在編碼時它的類型是可選擇的.即編碼器可以忽略這個元素,解碼器不能假設它將出現(xiàn).但當鄰接的兩個元素具有相同的類型時,會給解碼器帶來一些問題

        定義: Name ::= Type OPTIONAL

  例如:

      Float ::= SEQUENCE {

                                         Exponent     INTEGER OPTIONAL,

                                         Mantissa     INTEGER,

                                         Sign             BOOLEAN

                       }

         當解碼器讀取這個結構時,在它看來第一個整數(shù)(INTEGER)可能是Exponent,也有可能認為是Mantissa. 一般建議不使用這種方式定義結構.

 ?。迹玻荆J(DEFAULT).默認修改器允許容器包含默認值.如果待編碼的數(shù)據(jù)值等同于它的默認值,那么它將在發(fā)送的數(shù)據(jù)流中被忽略.例如:

      Command ::= SEQUENCE {

                                         Token         IA5String(NOP) DEFAULT,

                                         Parameter   INTEGER

                       }

         如果編碼器把Token看成是代表字符串NOP,那么序列將按照定義的那樣編碼為:

                      Command ::= SEQUENCE {

                                        Parameter    INTEGER

                      }

        <3>.選擇(CHOICE). 選擇修改器允許一個元素在給定的實例中可以有多個可能值.實質上說,解碼器將嘗試所有期望的解碼算法,直到有一個類型符合為止.當一個復雜的容器中包含其他容器時,時候選擇器就十分有用了.例如:

      UserKey ::= SEQUENCE {

                                       Name             IA5String,

                                       StartDate       UTCTIME,

                                       Expire            UTCTIME,

                                       KeyData        CHOICE {

                                              ECCKey        ECCKeyType,

                                              RSAKey        RSAKeyType

                                       }

                        }

         上例簡單的允許ECC也允許RSA密鑰的公鑰證書.

3.ASN.1數(shù)據(jù)類型

        ASN.1針對廣泛的應用定義了多種數(shù)據(jù)類型,我們這里只討論跟密碼學應用相關的數(shù)據(jù)類型.我們將討論如下數(shù)據(jù)類型: 
 
  布爾型 (Boolean);
        八位位組串 (OCTET String);
        位串 (BIT String);
        IA5String;
        可打印字符串 (PrintableString);
        整數(shù) (INTEGER);
        對象標識符 (OBJECT Identifier, OID);
        世界協(xié)調時 (UTCTIME);
        空 (NULL);
        序列,單一序列;
        集合;
        單一集合;
  任何ASN.1編碼都是以兩個字節(jié)開始(或者八位位組,含有8個二進制位),不管什么類型,它們都是通用的.第一個字節(jié)是類型標識符,也包含一些修正位;第二各字節(jié)是長度.

3.1 ASN.1頭字節(jié)

      頭字節(jié)(hearder byte)位于ASN.1編碼的開始,由3部分組成。如下圖:

    

        <1>. 類別位。

                 類別位(classification bits)由兩位表示,用來描述數(shù)據(jù)將要解釋的上下文。     

位8 位7 類別
0 0 通用(Universal)
0 1 應用(Application)
1 0 上下文特定(Context Specific)
1 1 專用(Private)

                  所有的類型中,通用類別最常用。

       <2>. 結構化位。

                結構化位(constructed bit)表示一個給定的編碼是否是相同類型的多種編碼的結構化。結構化元素是容器類型必需的,因為在邏輯上,它們只是其他元素的集合。

               結構化元素有自己的頭字節(jié)和長度字節(jié),之后是元素各個要素組件的單獨編碼。也就是說,這些要素組件是獨立地可解碼ASN.1數(shù)據(jù)類型。

               嚴格的說,容器類是唯一允許使用結構化位的數(shù)據(jù)類型。這是因為對于其他數(shù)據(jù)類型,給定內(nèi)容,只允許一種編碼。所以其他所有數(shù)據(jù)類型的結構化位都為0。

      <3>. 原始類型。

              ASN.1頭字節(jié)的低5位定義了32種ASN.1的原始類型(primitive type)

代碼 ASN.1類型 作用
1 布爾型 儲存布爾值
2 整數(shù) 儲存大整數(shù)
3 位串 存儲位數(shù)組
4 八位位串 存儲字節(jié)數(shù)組
5 預留位(例如在選擇修改器中)
6 對象標識符 標識算法及協(xié)議
16 序列和單一序列 未分類元素的容器
17 集合和單一集合 已分類元素的容器
19 可打印字符串 ASCII編碼(忽略一些不可打印字符)
22 IA5String ASCII編碼
23 世界協(xié)調時 以統(tǒng)一格式表示的時間


3.2 ASN.1長度編碼

根據(jù)編碼的實際長度,ASN.1定義了兩種長度編碼(length encoding)方法,長編碼和短編碼。

編碼字節(jié)的最高位代表的是短編碼還是長編碼;而低7位則形成一個長度立即數(shù)。

<1>. 短編碼。

        在短編碼中,負載的長度必須小于128字節(jié)。長度立即數(shù)用來表示負載的長度。例如,對于一個長度為65 (0x41)的負載進行編碼,其長度編碼字節(jié)只需簡單的設置為0x41即可。因為其最高位是0,則編碼器可以判斷出這是短編碼,而且長度是65。

<2>. 長編碼。

        在長編碼中,定義了附加的抽象數(shù)據(jù)來對長度進行編碼,它僅適用于所有長度為128字節(jié)或以上的負載。在這種模式下,長度立即數(shù)存儲的是為了表示負載長度所需的字節(jié)數(shù)。這個長度必須以big-endian格式進行編碼。(其實big endian是指低地址存放最高有效字節(jié)(MSB),而little endian則是低地址存放最低有效字節(jié)(LSB)。)。

         例如,為一個長度為47310 (0xB8CE)的負載進行編碼,因為它的長度大于127, 所以要采用長編碼方式。實際的長度需要兩個字節(jié)來表示。則,長度編碼字節(jié)為0x82; 然后用big-endian格式存儲的長度值為0xB8 0xCE。則全部長度編碼為 0x82 B8 CE。

3.3 ASN.1布爾類型

      布爾編碼的負載或者是全0或者是全1的八位位組。頭字節(jié)以0x01開始,長度編碼字節(jié)為0x01,負載內(nèi)容取決于布爾值的取值。

布爾值 編碼
False 0x01 01 00
True 0x01 01 FF


3.4 ASN.1整數(shù)類型

      整數(shù)類型表示一個有符號的任意精度的標量,它的編碼是可移植,平臺無關的。

      正整數(shù)的編碼比較簡單。每個字節(jié)表示的最大整數(shù)是255 (0xFF), 存儲的實際數(shù)值分成字節(jié)大小的數(shù)字,并且以big-endian格式存儲。例如:

  

八位位組{Xk, Xk-1,...., X0}將以遞減的順序從Xk到X0進行存儲.編碼規(guī)定正整數(shù)的第一個字節(jié)的最高位必須是0,即Xk的最高為必須是0,為1的話則為負數(shù).例如: x = 49468= 193 * 256 + 60 = 0xC1 * 0x FF + 0x3C; 即X1=0xC1, X0 = 0x3C. 按正常規(guī)定,編碼應該是 0x02 02 C1 3C, 但是X1的最高位是1, 應該被看成負數(shù).最簡單的方法是用前端零字節(jié)進行填充.編碼變?yōu)?0x02 02 00 C1 3C.

  負整數(shù)的編碼有些復雜.要先找到一個最小的256的冪,使它比要編碼的負數(shù)的絕對值還要大.例如:x = - 1555; 被1555大的256的最小的冪是256^2 = 65536; 然后將這個數(shù)跟負數(shù)相加以得到2的補碼. 65536 + (-1555) = 63981 =  0xF9 * 0xFF + 0x ED. 則編碼為 0x02 02 F9 ED.

      以下是一些常用整數(shù)編碼的例子.

編碼
0 0x02 01 00
1 0x02 01 01
2 0x02 01 02
127 0x02 01 7F
128 0x02 02 00 80
-1 0x02 01 FF
-128 0x02 01 80
-32768 0x02 02 80 00
1234567890 0x02 04 49 96 02 D2


3.5 ANS.1位串類型

      位串(BIT STRING)類型以可移植形式表示位數(shù)組.除了ASN.1頭部兩個字節(jié)之外,還有一個附加的頭部用來表示填充數(shù)據(jù)(通常是一個字節(jié),因為填充是為了形成一個完整的字節(jié)).編碼規(guī)則:位串的第一位放到第一個負載字節(jié)的第8位;位串的第二位放到第一個負載字節(jié)的第7位; 依此類推.填充滿第一個負載字節(jié),就繼續(xù)填充第二個負載字節(jié).如果最后一個負載字節(jié)未被填充滿,空的位用0來填充, 0的個數(shù)存放到頭部用來表示填充數(shù)據(jù)的那個字節(jié)里.

下面舉例說明:

有一個位串{1,0,0,0,1,1,1,0,1,0,0,1},開始填充負載字節(jié).第一個字節(jié)填充后為10001110 = 0x 8E; 第二個字節(jié)填充后為10010000 = 0x90, 低位4個0為填充的空位.則,負載為2個字節(jié)加上表示填充0個數(shù)的一個字節(jié)0x04總共3個字節(jié).則完整的編碼為:0x03 03 04 8E 90.

解碼器通過計算8 * 負載長度 - 填充數(shù) 來得到存儲輸出所需要的位數(shù).

3.6 ASN.1八位位組串類型

  八位位組串(OCTET STRING)是保存字節(jié)數(shù)組,它和位串類型(BIT STRING)很相似.這種編碼非常簡單,像其他類型一樣對頭部進行編碼,然后直接將八位位組復制過去即可.例如:對{FE, ED, 6A, B4}編碼;首先存儲類型0x04, 接著是長度0x04,然后是字節(jié)本身0xFE ED 6A B4; 完整的編碼為 0x04 04 FE ED 6A B4.

3.7 空類型

     空(NULL)類型實際上是"占位符", 它是含有空白選項的選擇修改器所特有.例如:

          MyAccount ::= SEQUENCE {

                    Name                            IA5String,

                    Group                           IA5String,

                   Credentials                    CHOICE{

                                                              rsaKey           RSAPublicKey,

                                                              passwdHash  OCTET STRING,

                                                              none               NULL

                                                         }

           }

     在上面這個結構中,賬號的證書應該包含一個RSA密鑰或一個密碼散列值或什么都沒有.

 空類型的編碼是 0x05 00.

3.8 ASN.1 對象標識符類型

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

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

      OID在公鑰算法標準中很流行,它指出證書綁定了哪種散列算法. 同樣,也有公鑰算法,分組算法,和操作模式的OID. 它們是一種高效且可移植的表示數(shù)據(jù)包中所選算法的形式.

      對OID的編碼規(guī)則:


前兩部分如果定義為x.y, 那么它們將合成一個字40*x + y, 其余部分單獨作為一個字節(jié)進行編碼.
每個字首先被分割為最少數(shù)量的沒有頭零數(shù)字的7位數(shù)字.這些數(shù)字以big-endian格式進行組織,并且一個接一個地組合成字節(jié). 除了編碼的最后一個字節(jié)外,其他所有字節(jié)的最高位(位8)都為1.
     舉例: 30331 = 1 * 128^2 + 108 * 128 + 123  分割成7位數(shù)字(0x80)后為{1,108,123}設置最高位后變成{129,236,123}.如果該字只有一個7位數(shù)字,那么最高為0.

     MD5 OID的編碼:

        1. 將1.2.840.113549.2.5轉換成字數(shù)組 {42, 840, 113549, 2, 5}.

        2. 然后將每個字分割為帶有最高位的7位數(shù)字,{{0x2A},{0x86,0x48},{0x86,0xF7,0x0D},{0x02},{0x05}}.

        3. 最后完整的編碼為 0x06 08 2A 86 48 86 F7 0D 02 05. 

3.9 ASN.1序列和集合類型

  序列(SEQUENCE)和單一序列(SEQUENCE OF)以及相應的集合(SET)和單一集合(SET OF)類型叫做"結構"類型或簡單容器.它們是一種用來把相關數(shù)據(jù)元素收集為一個獨立的可解碼元素的簡單方法.

      序列編碼有以下性質:

      1. 編碼是結構化的.即頭字節(jié)的位6必須設置. 

  2. 編碼的內(nèi)容是由ASN.1序列類型定義列表中的所有數(shù)據(jù)類型值的完全編碼所組成,并且按照它們出現(xiàn)的順序進行編碼,除非這些類型被可選(OPTIONAL)或默認(DEFAULT)關鍵字所引用.

  例:考慮如下序列

  User ::== SEQUENCE{

          ID        INTEGER,

          Active BOOLEAN

      }

     當取值為{32,TRUE}時,編碼為 0x 30 06 02 01 20 01 01 FF} 在ASN.1文檔里,使用空格來表示編碼的屬性.

 0x30 06

               02 01 20

               01 01 FF

3.10 ASN.1可打印字符串和IA5String類型

        可打印字符串(PrintableString)和IA5String類型定義了一種獨立于本地代碼頁和字符集定義,在任何平臺上都可以將ASCII字符串編碼為可讀字符串的可移植方法.

       可打印字符串對象是ASCII集合的一個有限子集,這個子集包括32,39,40~41,43~58,61,63以及65~122.

       IA5String類型的編碼對象是ASCII集合中的大多數(shù).包括NULL,BEL,TAB,NL,LF,CR以及32~126.

       可打印字符串和IA5String的編碼和八位位組串相似.可打印字符串的頭字節(jié)是0x13, IA5String的是0x16. 例如:"Hello World"的編碼為0x13 0B 48 65 6D 6D 6F 20 57 6F 72 6D 64.

3.11 ASN.1世界協(xié)調時類型

        世界協(xié)調時(UTCTIME)定義了一種相對GMT時間的標準時間(以日期)編碼.它使用"YYMMDDHHMMSSZ"的格式分別表示年,月,日,時,分,秒. 其中"Z"是遺留自初始的UTCTIME. 如果沒有"Z",就允許兩種附加組"[+/-]hh 'mm'",其中"hh"和"mm"分別為與GMT的時差和分差. 如果有"Z",則時間是以Zulu或GMT時間表示.

        字符串的編碼按照IA5String編碼規(guī)則進行轉換(ASCII字符集),其頭字節(jié)為0x17而不是0x16. 例如:

        July 4,2003 at 11:33 and 28 seconds編碼為"030704113328Z", 再編碼0x17 0D 30 33 30 37 30 34 31 31 33 33 32 38 5A.

下文轉自:http://blog.ednchina.com/l0p0c/153105/message.aspx

ASN.1即抽象語法符號,用來定義應用程序數(shù)據(jù)和表示協(xié)議數(shù)據(jù)單元的抽象語言。優(yōu)點是獨立于機器、語言及應用程序的內(nèi)部表示。適用于描述現(xiàn)代通信中復雜的、變化的、可擴展的數(shù)據(jù)結構。比如3G和VoIP均采用了ASN.1。
ASN.1分兩大部分:語法規(guī)則和編碼規(guī)則。
語法規(guī)則
1. ASN.1定義示例
Age  ::= INTEGER (0..120)
User ::= SEQUENCE {
         name    IA5String (SIZE(1..128)),
         age     Age DEFAULT 18,
         address  IA5String OPTIONAL,
         ...
       }
 
2. 簡單類型
基本類型
字符串類型
對象類型
其它類型
 
3. 構造類型
SEQUENCE,對應于C語言中的struct
SEQUENCE OF,對應于數(shù)組
SET,類似于SEQUENCE,但不考慮分量順序
SET OF,集合類型,每一分量類型相同,不考慮順序
 
4. 類型定義
語法:   typereference ::= Type
示例:
1) Counter      ::= INTEGER
2) UserAccount ::= SEQUENCE {
    username PrintableString,
    password PrintableString,
    account INTEGER
}
 
5. 賦值
語法: valuereference Type ::= Value
示例:
1) current Counter  ::= 1234
2) myAccount UserAccount ::= {
    username “tly”,
    password “guesswhat”,
    account 2345
}
 
 
編碼規(guī)則
1. BER
1) 三種情況及其格式:
a.簡單類型(Primitive),定長;
Identifier  |  Length  |  Content
b.構造類型(Constructed),定長;
Identifier  |  Length  |  I | L | C | I | L | C | ...
c.構造類型(Constructed),不定長;
Identifier  |  Length  |  I | L | C | I | L | C | EOC|
 
2) Identifier編碼
格式:   8     7     6     5    4    3    2    1
            Class    | P/C |     Tag    number
分兩種情況:
a.Tag number < 31
b.Tag number >= 31
 
3) Length及Content編碼
分三種情況:
a.短形(L < 128),定長
b.長形(L >= 128),定長
c.不定長,僅用于構造類型
 
4) 示例
a.INTEGER 49
0000 0010   0000 0001   0011 0001
 
b.UserAccount ::= SEQUENCE {
    username IA5String,
    account INTEGER
}
myAccount UserAccount ::= {
    username “john”,
    account 129
}
 
0011 0000  0000 1010
0001 0110  0000 0011
0100 1010  0110 1111
0110 1000  0110 1110
0000 0010  0000 0010
0000 0000  1000 0001
 
2. DER
為確保編碼的唯一性,出現(xiàn)了CER和DER兩種編碼方案,它們均為BER子集。其中DER只使用定長編碼,CER基于不定長編碼。
 
3. PER
在PER中,tag從不傳送,length和value如果雙方都知道,也不需傳送。因此,其編碼更精簡,效率更高。
1) 格式
preamble  |   length   |  contents
preamble:只出現(xiàn)在ENUMERATED、SEQUENCE、SET、CHOICE四種數(shù)據(jù)結構的編碼中。用來記錄結構中有無擴展項(extension)、選擇項(optional)或缺省項(default);
length: 對STRING、SEQUENCE OF、SET OF等數(shù)據(jù)類型進行編碼時,需對其長度按對齊方式進行編碼;
contents:若數(shù)據(jù)是基本結構類型,如:BOOLEAN、INTERGER、REAL、BITSTRING等,即可直接進行編碼;若數(shù)據(jù)是復合結構類型,如 SEQUENCE、SET、CHOICE、SEQUENCE  OF 等,則屬嵌套編碼,此時contents中也包含有preamble、length、contents三個部分。
 
2) 示例
a. cug-Index  INTEGER(1..256)的值為10時,PER編碼為(pad)00001001
b. error  CHOICE
{
  systemErr   NULL,
  operationErr  NULL,
  …
}
      若error值為systemErr,則PER編碼為00。
 
4. XER
即XML Encoding Rules,主要應用于網(wǎng)站開發(fā),本文不作介紹。
 
結束語:
      本文介紹了抽象語法符號1(ASN.1)的概念和數(shù)據(jù)表示方式,對BER編碼過程給出了較詳細的說明和示例,同時也簡要地介紹了ASN.1的其它編碼方法,如DER, PER, XER等。最近因學習3GPP之故,本人剛剛接觸ASN.1,難免有疏漏和錯誤,還請各位給予指正,同時也歡迎大家互相交流學習。
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
ASN.1筆記
如何查看證書的16進制DER編碼,及證書的各個域DER格式
ANS.1筆記
SNMP從入門到開發(fā):進階篇
如何看懂描述SNMP中MIB的ASN.1(轉)
ASN.1筆記——基本類型詳述
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服