3

我有这样的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 是例如 INTEGER 时,应用程序如何解释标记为 [0] 的 TLV 字段的值?

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

来自 ITU-T X.690:

8.1.4 内容八位字节

内容八位字节应由零个、一个或多个八位字节组成,并应按照后续条款中的规定对数据值进行编码。

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

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

4

1 回答 1

4

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

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

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

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

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

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

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

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

于 2017-08-03T10:30:40.167 回答