asn.1 格式學習


基本概念

抽象語法表示法一(abstract syntax notation one, ASN.1)是支持復雜數據結構和對象的定義、傳輸、交換的一系列規則。ASN.1是為了支持不同平台的網絡通信而設計,與機器架構以及語言實現無關。ASN.1於1988年最先在X.208中定義,最近的更新是在2008年推出的X.680系列文檔中。

ASN.1以一種抽象的方式定義數據,如何編碼數據則在另外一份標准里面。基本編碼規則(basic encoding rules, BER)是第一個數據編碼標准。X.509依賴於的唯一編碼規則(distinguished encoding rules,DER)是BER的子集,只允許一種方式編碼ASN.1的值,這種唯一性對密碼學尤其是數字簽名的使用非常關鍵。PEM(privacy-enhancedmail的簡寫,在此上下文中無含義)是DER使用Base64編碼后的ASCII編碼格式。

基本語法

類型

給定的ASN.1類型的值是該類型集合的元素。ASN.1有​​四種類型:簡單類型,是“原子的”並且沒有任何組件;具有組件的結構化類型;標記類型,從其他類型派生;和其他類型,包括CHOICE類型和ANY類型。可以使用ASN.1賦值運算符::=給類型和值命名,這些名稱可以用於定義其他類型和值。

除CHOICE和ANY外,每種ASN.1類型都有一個標簽,該標簽由一個類和一個非負標簽號組成。當且僅當它們的標簽號相同時,ASN.1類型才抽象地相同。換句話說,ASN.1類型的名稱不會影響其抽象含義,只有標簽會影響它的抽象含義。標簽分為四類:

  • Universal,用於在所有應用程序中含義相同的類型;這些類型僅在X.208中定義。
  • Application,用於特定於應用程序的含義的類型,例如X.500目錄服務;兩個不同應用程序中的類型可能具有相同的特定於應用程序的標簽和不同的含義。
  • Private,用於含義特定於給定企業的類型。
  • Context-specific,對於其含義特定於給定結構化類型的類型;特定於上下文的標記用於在給定的結構類型的上下文中區分具有相同基礎標記的組件類型,並且兩種不同結構類型的組件類型可能具有相同的標記和不同的含義。
Type Tag number(decimal) Tag number(hexadecimal)
INTEGER 2 02
BIT STRING 3 03
OCTET STRING 4 04
NULL 5 05
OBJECT IDENTIFIER 6 06
SEQUENCE and SEQUENCE OF 16 10
SET and SET OF 17 11
PrintableString 19 13
T61String 20 14
IA5String 22 16
UTCTime 23 17

ASN.1類型和值以靈活的類似於編程語言的表示法表示,並具有以下特殊規則:

  • 布局不重要;多個空格和換行符可以視為一個空格。
  • 注釋由一對連字符--或一對連字符和一個換行符分隔。
  • 標識符(值和字段的名稱)和類型引用(類型的名稱)由大小寫字母,數字,連字符和空格組成;標識符以小寫字母開頭;類型引用以大寫字母開頭。

基本編碼規則(BER)

ASN.1的基本編碼規則(縮寫為BER)提供了一種或多種方法來將任何ASN.1值表示為八位字節串。(當然,還有其他方法可以表示ASN.1值,但BER是在OSI中交換此類值的標准。)
有三種方法可以在BER下編碼ASN.1值,其選擇取決於值的類型以及值的長度是否已知。這三種方法是

  • 原始的定長編碼
  • 結構化定長編碼
  • 結構化不定長編碼

簡單的非字符串類型采用原始的定長方法。結構化類型采用兩種結構化方法之一;簡單字符串類型可以使用任何方法,具體取決於值的長度是否已知。通過隱式標記派生的類型采用基礎類型的方法,通過顯式標記派生的類型采用構造的方法。

在每種方法中,BER編碼都有三個或四個部分:

  • 標識符。這些標識ASN.1值的類和標記號,並指示該方法是原始的還是構造的。
  • 長度。對於定長方法,這些方法給出內容八位位組的數量。對於構造的不確定長度的方法,這些表明長度是不確定的。
  • 內容。對於原始的定長方法,這些給出了值的具體表示。對於構造的方法,這些方法給出了值成分的BER編碼的串聯。
  • 內容結尾。對於構造的不確定長度方法,這些表示內容的結尾。對於其他方法,則不存在。

原始的定長編碼

此方法適用於簡單類型以及通過隱式標記從簡單類型派生的類型。它要求事先知道值的長度。BER編碼的部分如下:

標識符

有兩種形式:低標簽號(用於0到30之間的標簽號)和高標簽號(用於31以上的標簽號)。

低標簽數形式。一八位字節。第8位和第7位指定了類別,第6位的值為0,表示編碼是原始的,第5-1位給出了標記號。

Class Bit 8 Bit 7
universal 0 0
application 0 1
context-specific 1 0
private 1 1

高標簽數形式。兩個或更多字節。第一個字節與低標簽號格式相同,除了位5-1的值均為1。第二個和隨后的字節給出標簽號,以基數128為基數,最高有效位在前,位數越少越好,每個字節的第8位(最后一位除外)設置為1

長度

有兩種形式:short(對於0到127之間的長度)和long(對於0到2 ^ 1008 -1之間的長度)。

  • short,一個字節。位8的值為0,而位7-1給出長度。
  • long,2至127個字節。第一個字節的位8的值為1,而第7-1位給出附加字節的數量。第二個和隨后的八位字節以256為基數,以最高有效數字在前。

內容

給出了值的具體表示形式(如果類型是通過隱式標記派生的,則可以給出基礎類型的值)

結構化定長編碼

標識符

同上,但是第6位是1

長度

同上

內容

值的組成部分的BER編碼的串聯:

  • 對於簡單的字符串類型和通過隱式標記從其派生的類型,該值的連續子字符串(隱式標記的基礎值)的BER編碼的串聯。
  • 對於結構化類型和通過隱式標記從其派生的類型,值的成分(隱式標記的基礎值)的BER編碼的串聯。
  • 對於通過顯式標記從任何內容派生的類型,基礎值的BER編碼。

結構化不定長編碼

此方法適用於簡單字符串類型,結構化類型,通過隱式標記派生的簡單字符串類型和結構化類型的類型,以及通過顯式標記派生自任何內容的類型。不需要預先知道值的長度。BER編碼的部分如下:

  • 標識符。同上。
  • 長度。一個字節,80
  • 內容。同上。
  • 內容結尾。兩個字節00 00

可分辨編碼規則(DER)

ASN.1的可分辨編碼規則(縮寫為DER)是BER的子集,並給出了一種將任何ASN.1值表示為八位字節字符串的精確方法。
DER在BER中給出的規則中增加了以下限制:

  • 當長度在0到127之間時,必須使用簡短的長度形式
  • 當長度為128或更大時,必須使用長形式的長度,並且長度必須以最少的八位位組數目進行編碼。
  • 對於簡單字符串類型和從簡單字符串類型派生的隱式標記類型,必須使用原始的定長方法。
  • 對於結構化類型,從結構化類型派生的隱式標記類型和從任何事物派生的顯式標記類型,必須使用構造的定長方法。

變量例子

  • BIT STRING value "011011100101110111"

    • 03 04 06 6e 5d c0 DER encoding
    • 03 81 04 06 6e 5d c0long form of length octets
    • 23 09 03 03 00 6e 5d 03 02 06 c0constructed encoding: "0110111001011101" + "11"
  • IA5String value "test1@rsa.com"

    • 16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6dDER encoding
    • 16 81 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6dlong form of length octets
    • 36 13 16 05 74 65 73 74 31 16 01 40 16 07 72 73 61 2e 63 6f 6dconstructed encoding: "test1" + "@" + "rsa.com"

例子

給出了X.501類型Name的ASN.1表示法

Name ::= CHOICE {
  RDNSequence }

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName

RelativeDistinguishedName ::=
  SET OF AttributeValueAssertion

AttributeValueAssertion ::= SEQUENCE {
   AttributeType,
   AttributeValue }

AttributeType ::= OBJECT IDENTIFIER

AttributeValue ::= ANY

用樹型表示就是這樣

|-Name CHOICE
   |-RDNSequence SEQUENCE OF
        |-RelativeDistinguishedName SET OF
            |-AttributeValueAssertion SEQUENCE
                |-AttributeType OBJECT IDENTIFIER
                |-AttributeValue ANY

本節從下至上給出了一個Name類型的值的DER編碼示例。
該名稱是PKCS示例[Kal93]中測試用戶1的名稱。該名稱由以下路徑表示:

            (root)
               |
        countryName = "US"
               |
organizationName = "Example Organization"
               |
    commonName = "Test User 1"

每個級別對應一個RelativeDistinguishedName值,對於該名稱,每個級別都由一個AttributeValueAssertion值組成。AttributeType值在等號之前,AttributeValue值(給定的屬性類型打印字符串)是等號后。
countryName, organizationNamecommonUnitName是X.520定義的屬性類型:

attributeType OBJECT IDENTIFIER ::=
  { joint-iso-ccitt(2) ds(5) 4 }

countryName OBJECT IDENTIFIER ::= { attributeType 6 }

organizationName OBJECT IDENTIFIER ::=
  { attributeType 10 }

commonUnitName OBJECT IDENTIFIER ::=
  { attributeType 3 }
  • AttributeType
    上述 countryName, organizationName, commonName 的值均為 OCTET STRING. 因此他們的 DER 編碼方法應該為 primitive, definite-length. 對於 OBJECT IDENTIFIER 類型, Identifier 字段應該為 06. bit8 和 bit7 為 0, 代表 Universal class

    06 03 55 04 06  countryName
    06 03 55 04 0a  organizationName
    06 03 55 04 03  commonName
    
  • AttributeValue
    假設上述 countryName, organizationName, commonName 屬性的值類型均為 PrintableString, 且值分別為 “US”, “Example Organization”, “Test User 1”.
    編碼結果分別為:

    13 02 55 53  // "US"
    13 14 45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61 74 69 6f 6e // "Example Organization"
    13 0b 54 65 73 74 20 55 73 65 72 20 31 // "Test User 1"
    
  • AttributeValueAssertion

    30 09           // countryName = "US"
        06 03 55 04 06
        13 02 55 53 
    30 1b           // organizationName = "Example Organization"
        06 03 55 04 0a
        13 14 45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61 74 69 6f 6e
    30 12          // commonName = "Test User 1"
        06 03 55 04 0b
        13 0b 54 65 73 74 20 55 73 65 72 20 31
    
  • RelativeDistinguishedName

    31 0b
        30 09 ... 55 53
    31 1d
        30 1b ... 6f 6e
    31 14
        30 12 ... 20 31
    
  • RDNSequence

    30 42
        31 0b ... 55 53
        31 1d ... 6f 6e
        31 14 ... 20 31
    
  • Name
    CHOICE相當於聯合體,所以和RDNSequence一樣

    30 42
        31 0b
            30 09                                   
                06 03 55 04 06 // attributeType = countryName           
                13 02 55 53 // attributeValue = "US"
        31 1d
            30 1b
                06 03 55 04 0a // attributeType = organizationName                 
                13 14 45 78 61 6d 70 6c 65 20 4f 72 67 67 61 6e 69 7a 61 74 69 6f 6e  // attributeValue = "Example Organization"
        31 14
            30 12
                06 03 55 04 03 // attributeType = commonName                   
                13 0b 54 65 73 74 20 55 73 65 72 20 31 // attributeValue = "Test User 1"
    

把數據放到文件中,去在線asn.1解析,成功解析

參考鏈接

A Layman's Guide to a Subset of ASN.1, BER, and DER
ASN.1 學習
ASN.1 JavaScript decoder


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM