簡體   English   中英

ASN.1 中隱式和顯式標簽的編碼

[英]Encoding of implicit and explicit tags in ASN.1

我試圖了解 IMPLICIT 和 EXPLICIT 標簽實際上是如何以 DER 二進制形式編碼的。

基本的例子很清楚。 普通integer,

x INTEGER ::= 5

被編碼為 TLV 三元組02 01 05

x [2] IMPLICIT INTEGER ::= 5

隱式標簽82替換現有標簽02和 forms 另一個 TLV: 82 01 05 ,並且在

x [3] EXPLICIT INTEGER ::= 5

在原始 TLV 周圍添加了一個包裝器: A3 03 02 01 05

現在我正在看一個更復雜的案例

30 42 A1 40 30 0D 82 0B  77 77 77 2E 62 61 64 2E
6F 72 67 30 09 82 07 62  61 64 2E 63 6F 6D 30 0D
81 0B 62 61 64 40 62 61  64 2E 6F 72 67 30 09 81
07 62 61 64 2E 63 6F 6D  30 0A 87 08 0A 00 00 00
FF 00 00 00

它被解碼成

SEQUENCE {
  [1] {
    SEQUENCE {
      [2] www.bad.org
    }
    SEQUENCE {
      [2] bad.com
    }
    SEQUENCE {
      [1] bad@bad.org
    }
    SEQUENCE {
      [1] bad.com
    }
    SEQUENCE {
      [7] 0A000000FF000000
    }
  }
}

我的問題是,我怎么知道A1是一個隱式標簽[1] IMPLICIT SEQUENCE ,它取代了原始標簽10 ,並且包含五個 TLV 元素(序列),還是一個環繞這五個元素的顯式標簽? 什么是A1

顯式標簽可以包裹多個 TLV 元素嗎?

“constructed”標志(第 6 位)指示標記是顯式還是隱式,這是否正確? 或者我是否需要查看包裝紙和被包裝物的長度?

我不假設二進制數據是正確的,所以另一種可能性是A1 40環繞以下序列30 0D... ,長度不匹配並且數據必須被拒絕。

你問了幾個問題,但每個問題都應該有一個單獨的答案。

標簽本身不是隱式或顯式的。 “標記”(將標記添加到類型的操作)是隱式的或顯式的。

考慮這樣一個事實:在 ASN.1 中,每個基本類型(例如 INTEGER、BOOLEAN)或類型構造函數(CHOICE 除外)(例如 SEQUENCE)都有一個內置的“通用”標簽。 例如,類型 INTEGER 具有內置標簽 UNIVERSAL 2,類型 OBJECT IDENTIFIER 具有內置標簽 UNIVERSAL 6,每個 SEQUENCE 類型具有內置標簽 UNIVERSAL 16,等等。 這並非特定於 BER/DER。 這是類型本身的屬性。

當一種類型作為另一種類型(例如,SEQUENCE 或 CHOICE)的組件出現時,它通常(但不總是)被分配另一個標簽。 新標簽可以替換現有標簽或插入現有標簽之前。 這就是隱式標記和顯式標記。 在隱式標記中,新標記會替換它所應用的類型的現有標記。 在顯式標記中,新標記位於現有標記的前面。 這也不是 BER/DER 特有的,它是 ASN.1 的一個特性。 一些編碼規則(BER、DER、OER在一定程度上)在編碼中使用標簽,而其他編碼規則(PER、JER)在編碼中不包含標簽。 盡管如此,標簽的存在獨立於所使用的編碼規則。

對給定類型使用隱式標記還是顯式標記取決於幾件事。 首先,模塊 header 中指定了默認標記(EXPLICIT TAGS、IMPLICIT TAGS、AUTOMATIC TAGS),它為模塊中存在的類型建立了默認標記模式。 (“默認默認”是顯式標記。)其次,可以通過在“]”之后使用關鍵字 IMPLICIT 或 EXPLICIT 來覆蓋特定類型模塊的默認標記。 第三,在某些情況下,標記必須是明確的。

如果您在模塊 header 中指定 AUTOMATIC TAGS,進程將生成並應用連續標簽,從“上下文特定”0 開始,到每個序列類型、集合類型和選擇類型的每個組件,不包含文字在其任何組件中標記。 自動標記過程應用隱式標記,這意味着每個生成的標記將替換現有標記。

有一些限制和一些特殊情況。 一是 CHOICE 類型沒有自己的通用標記,因此不可能將隱式標記應用於前面沒有文字標記(沒有要替換的標記)的 CHOICE 類型。 如果您不使用 AUTOMATIC TAGS 並且不向選擇類型添加新標簽,則選擇類型將保持沒有自己的標簽。 在 BER/DER 中,解碼器仍然可以通過查看即將到來的標簽來檢測未標記的選擇類型的存在,該標簽屬於存在的選擇選項。

上圖表明 BER/DER 解碼器將如何解釋編碼中的下一個標簽是不可能有歧義的。 標記過程將明確定義的標記(通常是一個或兩個標記,或者在未標記選擇類型的情況下可能沒有標記)分配給模塊中的每個類型,包括復雜類型的組件類型。 如上所述,這些標簽是 ASN.1 模式中存在的每種類型的屬性。 在 BER 和 DER 中,編碼器將只插入它正在編碼的每個值的類型的所有標簽。 如果值的類型有一個標簽,編碼器將產生一個 TLV。 如果值的類型有兩個標簽,編碼器將產生兩個嵌套的 TLV。 其實很簡單。 解碼器將知道會發生什么。

Alessandro 為您提供了有關標記的出色教程。 一些快速的補充要點:

通用 BER 解碼器可以將 BER 數據解碼為 TLV 層次結構,但您通常需要具有架構才能知道如何將其與 ASN.1 類型相關聯。

標簽應用於類型,因此,不,您不能添加顯式標簽來包裝多個 TLV 元素。 它將包裝單個 TLV。

構造標志告訴您 TLV 中的 V(值)本身是否是 TLV。 某些類型(例如 BIT STRING)可以以構造形式或原始形式進行編碼。 當一個類型被顯式標記時,它總是會產生一個帶有構造標志集的 TLV,但這並不是唯一一次使用構造標志。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM