【问题标题】:Interpreting ASN.1 indefinite-lenght encoding with multiple encapsulated octet-strings用多个封装的八位字节字符串解释 ASN.1 不定长度编码
【发布时间】:2018-01-10 19:08:21
【问题描述】:

我有这样的 BER 结构...

$ openssl asn1parse -inform der -in test.der -i -dump

 ????:d=4  hl=2 l=inf  cons:     cont [ 0 ]
 ????:d=5  hl=3 l= 240 prim:      OCTET STRING
      0000 - AABBCCDD
 ????:d=5  hl=2 l=   8 prim:      OCTET STRING
      0000 - EEFF
 ????:d=5  hl=2 l=   0 prim:      EOC

...或der2ascii 风格...

[0] `80`
  OCTET_STRING { `AABBCCDD` }
  OCTET_STRING { `EEFF` }
`0000`

我所知道的:无限长度编码必须包含构造类型,因为原始类型可能会引入歧义,例如当包含 0x0000 时。我想知道的是:解码器在解析这个 BER 结构时必须如何表现?两个 OCTET STRING 的标头字节是否包含在编码中?如果是,不定长字节数据是如何编码的?当第二个 OCTET STRING 是例如,应用程序如何解释标记为 [0] 的 TLV 字段的值一个整数?

我问这个问题,因为在 CMS 标准中,一个字段被定义为单个 OCTET STRING,但在大多数 BER 编码中,我总是看到其中两个。这仅仅是由于不确定长度编码吗?我错过了什么吗?

来自 ITU-T X.690:

8.1.4 内容八位字节

内容八位位组应由零个、一个或多个八位位组组成,并应编码数据值,如 后续分句。

注意——内容字节取决于数据值的类型; 后续子句遵循与类型定义相同的顺序 在 ASN.1 中。

这是否意味着,我可以放置每个构造的类型,而应用程序必须只解释构造的 TLV 结构的值部分?

【问题讨论】:

    标签: encoding asn.1 variable-length der ber


    【解决方案1】:

    当您以不定长模式对原始 OCTET STRING 进行编码时,编码器必须:

    • 将值拆分为较小的八位字节字符串块
    • 以定长模式对每个块进行编码,以便每个块都有自己的 TLV(有长度!)
    • 整个定长编码的原始 OCTET STRING 序列必须由单个、不定长编码的构造 OCTET STRING“容器”构成,该“容器”具有自己的 TLV(无长度,但具有八位字节结束标记)

    在另一端,解码器从内部的、确定长度的 OCTET STRING 块中提取 V 部分(删除它们的 TL 标头)。然后按照到达的顺序将 V 加入/消耗在一起,丢弃外帧的 TL 部分。

    请注意,不定长度编码技术背后的想法是编码器和解码器都可以发出/消耗不完整的、可能过大的数据。

    块大小由编码器/应用程序根据数据可用性、内存情况以及解码器缓冲能力的估计来选择。我认为 X.280/X.680 论文中的某处提到了这一点。

    编码器不允许将不同 ASN.1 类型的块放入任何单个不定长编码的容器中。换句话说,所有块必须与外部容器的类型相同。

    这应该可以解释为什么您可能会在不定长度编码的 BER/CER 流中看到多个(取决于块大小)八位字节串,而预期只有一个八位字节串。

    DER 禁止无限长度编码,因为相同数据的序列化表示可能会在重新编码时发生变化(由于可能会更改块大小)。

    【讨论】:

    • 所以,当块是进程时,必须丢弃它们的标头,对吗?如果块具有不同的类型,这是否也定义了,例如整数?生成块的过程是否在任何地方定义? PS:我将改写我的问题以使用 BER。我正在查看的标准基本上是 DER,但有时允许 BER 构造...
    • 更新了答案。
    猜你喜欢
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    相关资源
    最近更新 更多