ASN.1 中隐式和显式标签的编码

klk*_*206 7 asn.1 der ber

我试图了解隐式和显式标签实际上是如何以 DER 二进制形式编码的。

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

x INTEGER ::= 5
Run Code Online (Sandbox Code Playgroud)

被编码为 TLV 三元组02 01 05。在

x [2] IMPLICIT INTEGER ::= 5
Run Code Online (Sandbox Code Playgroud)

隐式标记82替换现有标记02并形成另一个 TLV:82 01 05,并且在

x [3] EXPLICIT INTEGER ::= 5
Run Code Online (Sandbox Code Playgroud)

在原始 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
Run Code Online (Sandbox Code Playgroud)

被解码为

SEQUENCE {
  [1] {
    SEQUENCE {
      [2] www.bad.org
    }
    SEQUENCE {
      [2] bad.com
    }
    SEQUENCE {
      [1] bad@bad.org
    }
    SEQUENCE {
      [1] bad.com
    }
    SEQUENCE {
      [7] 0A000000FF000000
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,我如何知道A1它是一个隐式 tag [1] IMPLICIT SEQUENCE,它替换了原始 tag 10,并且包含五个 TLV 元素(序列),还是一个包含这五个元素的显式 tag ?什么是A1

显式标签可以包裹多个 TLV 元素吗?

“构造”标志(位 6)指示标签是显式的还是隐式的,这是否正确?或者我需要查看包装纸的长度和被包装的东西吗?

我并不假设二进制数据是正确的,因此另一种可能性是A1 40环绕以下序列30 0D ...,长度不匹配,并且数据必须被拒绝。

Ale*_*dro 13

您提出了几个问题,但每个问题都应该得到单独的答案。

标签本身不是隐式的或显式的。“标记”(向类型添加标记的操作)可以是隐式的,也可以是显式的。

考虑以下事实:在 ASN.1 中,除了 CHOICE(例如 SEQUENCE)之外的每个基本类型(例如,INTEGER、BOOLEAN)或类型构造函数都具有内置的“通用”标记。例如,类型 INTEGER 具有内置标签 UNIVERSAL 2,类型 OBJECT IDENTIFIER 具有内置标签 UNIVERSAL 6,每个 SEQUENCE 类型具有内置标签 UNIVERSAL 16,等等。这并非特定于 BER/DER。它是类型本身的属性。

当一种类型作为另一种类型(例如,SEQUENCE 或 CHOICE)的组件出现时,它通常(但并非总是)被分配另一个标签。新标签可以替换现有标签或插入到现有标签之前。这就是隐式标记和显式标记。在隐式标记中,新标记将替换其所应用类型的现有标记。在显式标记中,新标记将作为现有标记的前缀。这也不是 BER/DER 特有的,它是 ASN.1 的一项功能。某些编码规则(BER、DER 和有限范围内的 OER)在编码中使用标签,而其他编码规则(PER、JER)在编码中不包含标签。尽管如此,标签的存在与所使用的编码规则无关。

对于给定类型是否使用隐式或显式标记取决于一些因素。首先,模块头中指定了默认标记(显式标记、隐式标记、自动标记),它为模块中存在的类型建立默认标记模式。(“默认默认值”是显式标记。)其次,可以通过在“]”之后使用关键字 IMPLICIT 或 EXPLICIT 来覆盖特定类型的模块的默认标记。第三,在某些情况下,标签必须是明确的。

如果您在模块头中指定 AUTOMATIC TAGS,进程将生成连续标签并将其应用到从“上下文特定”0 开始的每个序列类型、集合类型和选择类型(不包含文字)的每个组件标记其任何组件。自动标记过程采用隐式标记,这意味着每个生成的标记都会替换现有标记。

有一些限制和一些特殊情况。一是 CHOICE 类型没有自己的通用标记,因此不可能将隐式标记应用于前面没有文字标记的 CHOICE 类型(没有要替换的标记)。如果您不使用自动标签,也不向选择类型添加新标签,则选择类型将保持不变,没有自己的标签。在 BER/DER 中,解码器仍然可以通过查看即将到来的标签来检测未标记的选择类型的存在,该标签属于存在的选择替代方案。

上面显示了 BER/DER 解码器如何解释编码中的下一个标签,不会有任何歧义。标记过程将明确定义的标记(通常是一个或两个标记,或者在未标记的选择类型的情况下可能没有)分配给模块中的每种类型,包括复杂类型的组件类型。如上所述,这些标签是 ASN.1 模式中存在的每种类型的属性。在 BER 和 DER 中,编码器将仅插入其正在编码的每个值的类型的所有标签。如果值的类型有一个标签,则编码器将生成一个 TLV。如果值的类型有两个标签,则编码器将生成两个嵌套的 TLV。其实很简单。解码器会知道会发生什么。