使用多个封装的八位字节串

时间:2017-08-03 09:11:47

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

我有这样的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字段的值。 INTEGER?

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

来自ITU-T X.690:

  

8.1.4内容八位字节

     

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

     

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

这是否意味着,我可以将每个构造的类型和应用程序只能解释构造的TLV结构的值部分?

1 个答案:

答案 0 :(得分:4)

在无限长模式下对基本OCTET STRING进行编码时,编码器必须:

  • 将值拆分为较小的OCTET STRING的块
  • 以定长模式对每个块进行编码,使每个块都有自己的TLV(长度为!)
  • 定长编码原语OCTET STRING的整个序列必须由单个,不定长度编码构造的OCTET STRING"容器"拥有自己的TLV(没有长度,但具有八位字节末尾的哨兵)

在另一端,解码器从内部,确定长度的OCTET STRING块中提取V部分(丢弃它们的TL头部)。然后按照到达顺序连接/消耗V,从而丢弃外框的TL部分。

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

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

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

这应该有希望解释为什么在不确定长度编码的BER / CER流中可能会看到多个(取决于块大小)OCTET STRING,其中只需要一个OCTET STRING。

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