1

我有一个 ASN.1 语法规范,我希望通过添加一些字段来修改它。如果我使用带有新字段的 BER 创建一个编码字符串,然后尝试使用不知道这些附加字段的解码器对该字符串进行解码,结果应该是什么?解码会因为解码器无法识别的字段而失败吗?解码器会只解码它可以识别的字段并完全忽略它不能识别的字段吗?这是否完全是一个解码器实现问题,所以任何一个结果都是可能的,取决于解码器是如何实现的?

现在,我正在使用开源 ASN.1 编译器/解码器,它似乎完全失败了,但我不确定这是因为实施还是因为 ASN.1 规则规定了这种结果?

4

2 回答 2

3

它当然不依赖于实施。也就是说,如果不同的实现以不同的方式处理它,那么其中之一就是做错了。如果您使用不期望未知字段的解码器来解码未知字段,则解码应该会失败。它不会跳过未知字段。

然而,有一种方法可以在它们已知之前提供额外的字段。它是使用扩展标记(“...”)。假设我们开发了各种版本的 ASN.1 规范。我们称它们为 V1、V2、V3 等。V1 是最初的规范,但我们在设计 V1 时就明白,很可能在某个时候我们必须对其进行修改。为了允许这一点,而不是像

Z ::= SEQUENCE { a INTEGER,
                 b OCTET STRING,
                 c Message1
}

我们会像这样声明 Z 是可扩展的

Z ::= SEQUENCE { a INTEGER,
                 b OCTET STRING,
                 c Message1,
                 ...
}

扩展标记表示,在 c 之后,可能还有更多未知的字段。解码器应将包含此类字段的消息视为有效,只要它们遵循 c。解码器将无法解码它们,因为它不知道它们应该是什么,但它知道它们是允许的。

假设我们通过插入两个新字段来将 V1 更新为 V2,有点像这样

Z ::= SEQUENCE { a INTEGER,            -- V1
                 b OCTET STRING,       -- V1
                 c Message1,           -- V1
                 ...,
             [[  d PrintableString,    -- V2
                 e BOOLEAN          ]] -- V2
}

在这种情况下,V1 版本可以与 V2 版本互操作。V1 编码器不包括 d 或 e,而 V2 编码器将包括它们。从解码器的角度来看,V1 解码器将接受(但不解码)d 和 e,而 V2 解码器将在找到 d 和 e 时对其进行解码。因此,V1 解码器将同时接受 V1 和 V2 编码,只要找到 d 和 e 就忽略它们;V2 解码器也将接受 V1 和 V2 编码,注意 V1 编码不包括 d 或 e,但它仍然有效。

我们可以通过其他版本继续这一点,例如,

Z ::= SEQUENCE { a INTEGER,            -- V1
                 b OCTET STRING,       -- V1
                 c Message1,           -- V1
                 ...,
             [[  d PrintableString,    -- V2
                 e BOOLEAN         ]], -- V2
             [[  f PrintableString,    -- V3
                 g ExtensionMessage]]  -- V3
}

其中 V1、V2 和 V3 都可以互操作。

但是请注意,由于我们正在处理 SEQUENCE,因此必须保留顺序。你不可能有没有 d 的 e,也没有没有 d、e 和 f 的 g。

因此,结论是,如果您的类型定义包含扩展标记,您可以添加新字段,但如果没有,您可能不会。

于 2010-03-01T04:29:49.193 回答
0

这一切都取决于规范和实现。简而言之 - 没有办法告诉。这取决于实施。使用 asn.1 的任何给定协议/格式的某些规范将明确声明将忽略未知元素,在这种情况下,解码不应失败。

但更常见的是,解码器将拒绝任何不严格符合它应该解码的 ASN.1 语法的输入。

于 2010-02-26T19:28:15.437 回答