【问题标题】:What does ASN.1/BER "Constructed" actually mean?ASN.1/BER“构造”实际上是什么意思?
【发布时间】:2022-01-09 13:09:31
【问题描述】:

很多地方说第 6 位表示构造。但这是什么意思?

Seams 的意思是“显式”[nn] 前缀,可以添加到序列成员中。

但序列通常似乎开始 30x,但接下来只是长度和值。都说Sequences总是“构造”的,是不是说10x是非法的?

我们将不胜感激。

【问题讨论】:

  • 在这里构造的意思是“不是原始的”,正如所有那些“很多地方”如何在这两件事之间建立明确的二分法所证明的那样。当我尝试使用搜索引擎时,我可以在页面摘要中找到:“构造类型是那些将相似或不同的原始类型组合成有序或无序组的类型”。即,constructed 类型是具有 structure 的类型,并且对应于类 C 语言中的 struct
  • 另外,ASN.1 中的括号 [number] 用于除“通用”标签之外的标签,如 INTEGER 和 BIT STRING。此类标签可以显式或隐式编码,并且总是构造显式标签,因为它们的 V 本身就是“底层”TLV,而隐式标签的 V 只是底层 V,并且可能是构造的或原始的,具体取决于底层类型(其中未编码)。你见过en.wikipedia.org/wiki/X.690# 吗?

标签: asn.1


【解决方案1】:

https://www.itu.int/rec/T-REC-X.680-202102-I/en中解释了EXPLICIT

构造在https://www.itu.int/rec/T-REC-X.690-202102-I/en中解释

注意:constructed 仅用于描述编码,没有构造类型。

constructed encoding:一种数据值编码,其中的内容 八位位组是一个或多个数据值的完整编码


在标签/长度/值编码(如 ASN.1 BER、CER、DER)中,值可以是叶或节点。

如果Value是叶子,则Tag的构造位为假

如果Value是一个节点(意味着Value实际上是另一个Tag/Lenght/Value),Tag的构造位为真

您可以在 2 种情况下发现构造位设置为 true(参见下面的示例):

  1. 您使用了显式标记
  2. 您的价值类型强加或允许将价值分成几部分(然后,每部分都有自己的标签/长度

显式标记

Schema DEFINITIONS ::= 
BEGIN
  My-Integer1 ::= [0] EXPLICIT INTEGER   -- TLTLV where first T is constructed
  My-Integer2 ::= [1] IMPLICIT INTEGER   -- TLV                                           
END

如果您使用 My-Integer1 编码发送 1(整数值)将是 A003 0201 01 (TLTLV)

如果您使用 My-Integer2 编码发送 1(整数值)将是 8101 02 (TLV)


可以分解成部分的值:

一个明显的例子是 SEQUENCE OF...

Schema DEFINITIONS ::= 
BEGIN
  My-SEQUENCE ::= SEQUENCE OF INTEGER         
END

如果您发送一个包含 3 个整数 (1,2,3) 的列表,则会构造第一个标签

OSS ASN-1Step Version 10.2
Copyright (C) 2021 OSS Nokalva, Inc.  All rights reserved.
This product is licensed for use by "OSS Nokalva, Inc."

C0043I: 0 error messages, 0 warning messages and 0 informatory messages issued.


ASN1STEP: Encoding of value notation  for PDU #1:

Encoding to the file 'data.ber' using BER encoding rule...
My-SEQUENCE SEQUENCE OF: tag = [UNIVERSAL 16] constructed; length = 9
  INTEGER: tag = [UNIVERSAL 2] primitive; length = 1
    1
  INTEGER: tag = [UNIVERSAL 2] primitive; length = 1
    2
  INTEGER: tag = [UNIVERSAL 2] primitive; length = 1
    3
Encoded successfully in 11 bytes:
30090201 01020102 020103

一个不太明显的例子是一个字符串(因为它可能很长,所以可以分成几部分)。请参阅 x690 规范中的示例 8.23.5.4

Name ::= VisibleString

“Jones”的值可以用 3 种不同的方式编码:

  1. 1A 05 4A6F6E6573(标签1A是原始形式)
  2. 3A 09 04034A6F6E1 04026573(标签 3A 构造形式:“Jones”分为 2 部分“Jon”和“es”)
  3. 3A 80 04034A6F6E1 04026573 0000(与2相同。但我们不知道总长度......我们只希望0000结束)

【讨论】:

  • If Value is a node (meaning that Value is in fact another Tag/Lenght/Value), Tag's constructed bit is true -- 我要补充一点,这并不总是正确的。比如BIT_STRINGOCTET_STRING可以构造,但是标签值是原始的(构造位设置为0)。
  • @Crypt32:在构造的 TLV 中,“V”部分(在 X.690 中称为“内容八位字节”)由(零个或多个)TLV 的串联组成。这由“T”部分中的“constructed”位设置为 1 来表示。如果您有一个被编码为构造编码的八位字节字符串值,则对应于八位字节字符串值的 TLV 中的“T”部分将将其“构造”位设置为 1,其“V”部分将由(零个或多个)TLV 的串联组成。这些子 TLV 中的每一个本身都可以是原始的或构造的。
  • @Crypt32:我不是专门指 DER,最初的问题也没有提到 DER。 DER 限制和禁止 BER 中允许的几件事,以实现规范编码。除其他外,DER 禁止对八位字节字符串使用构造编码等。如果我没看错,您不能只对八位字节字符串值使用分段编码(嵌套 TLV)并将原始/构造位设置为0.
  • @Crypt:您的示例未显示位字符串值的构造编码。位串值的构造编码将是位串的位被分成多个段并且每个段被编码到其自己的 TLV 中,就好像它本身就是一个位串值一样。如果我正确阅读了您的示例,它会显示 BIT STRING 的编码(CONTAINING >>)。在您的示例中,位字符串的位由序列值的编码组成,这显然是一种构造编码。
  • 请参阅 X.690 的第 8.6.3、8.6.4 等条款,其中指定了位串值的构造编码是什么。您的示例显示了位串值的原始编码,而不是构造的编码。 TLV 的“V”部分仅包含位串值的位,没有分段。然后(单独)位字符串包含序列的编码,因为它以这种方式受到约束。
猜你喜欢
  • 1970-01-01
  • 2018-08-08
  • 1970-01-01
  • 1970-01-01
  • 2020-02-15
  • 1970-01-01
  • 2021-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多