解析 X.509 ASN.1 二进制数据

Parsing X.509 ASN.1 binary data

根据this文章,在论文中可以看到如下内容:

  1. 我们能不能把上面的X.509文法看成这样:SEQUENCE和SET元素是非终结符,其余的都是终结符。因此我们也可以重写语法如下:

     Certificate = A
     signatureAlgorithm = c
     signature = d
     ToBeSigned = T
    
     S => A | AA    ; either a single or many Certificate elements
     A => TA | Tcd  ; TA supports TA, TTA, TTTA, so we can have multiple T non-terminals (cd are non-terminals: signartureAlgorithm and signature which come at the end)
     T = vs...e     ; all of the elements from version, serialNumber, ..., extensions
    

将上述内容转换为更可用的标准字母语法的最佳方法是什么:我们能否将所有 ToBeSigned 元素简单地视为非终结符:vertor = v、serialNumber = s 等?

  1. 根据Chomsky Hierarchy,这是哪种语法?是正规语法吗?

Can we treat the above X.509 grammar as this: the SEQUENCE and SET elements are non-terminals, while the rest are terminals?

我会说这基本上是一个类别错误。但即使不是,它也不是 ASN.1 类型的特别有用的模型。

一个终端是一个没有语法结构的原子单位。 (至少,这是对终端的一种直觉。在乔姆斯基的上下文无关语法中,定义更简单:它是一个不会出现在任何产生式左侧的符号。)但是该摘录中的许多类型X.509 文档中确实有定义,因此它们肯定不是终端。可以说,BIT STRING 是一个终端,因为它或多或少是一种原始的 ASN.1 类型,但在 BER 和 DER 配置文件中的具体语法中,它实际上也是一个非终端。

"ASN"是"Abstract Syntax Notation"的缩写;避免英语名词短语的歧义,是书写抽象句法的符号。 ASN.1 从具体语法中抽象出来。这是一种专注于复杂数据对象内部结构相互关系的方法,而不会陷入解析或生成句子的现实世界机制中。从这个意义上说,它或多或少是乔姆斯基语法的镜像;乔姆斯基的目标(在提出层次结构的著名论文中)是从语义中抽象出来,只留下解析和生成句子的机制。正是在这个意义上,我认为这里的问题是一个类别错误;它试图统一两个本质上是分离概念的概念系统。

最后一点,我认为您可能误解了 SEQUENCE 的 ASN.1 概念,它不同于 SEQUENCE OF。粗略地说,A SEQUENCE 是 C struct 之类的抽象;它是具有命名成员的单一复合类型。这不是重复。如果你想表达相同类型对象的有序列表的概念,你可以使用SEQUENCE OF,它有点类似于C数组,尽管长度限制可以灵活得多。

SETSET OF是一样的,只不过是无序。我不知道有任何语言可以实现类似于 ASN.1 SET 的东西,而且我不确定这样的东西会有什么优势。但是 SET OF 类型肯定存在于许多语言中,它们通常被称为“无序多重集”之类的东西。 (同样,ASN.1 允许对特定 SET OF 对象指定复杂约束。一个常见的用例是将映射类型表示为 SET OF 双元素 SEQUENCEs。

ASN.1 也有一个 CHOICE 复合类型,它(像 C++ std::variant)表示指定类型列表之一的单个对象。

ASN.1 的一个有趣特性是它允许递归定义(尽管它不允许无限具体对象,因此递归元素需要是可选的或在可能为空的 SEQUENCE OF/SET OF 复合。递归定义至少打开了非常规文法的可能性。

ASN.1 工具根据一组 ASN.1 描述构建序列化器(生成器)和反序列化器(解析器)。可以使用多种表示方案,其中大多数需要比 ASN.1 中定义的抽象语法更复杂的语法。例如,在 BER 中,对象和字符串的序列可以通过在元素前面加上精确的长度来透明地表示,或者作为一系列子序列块后跟一个“序列结束”标记。甚至整数前面都有长度指示符,因为不受约束的 ASN.1 整数没有大小限制。 (ASN.1定义可以应用一个约束,一些表示方案使用这个约束来简化具体表示。)

X.509 证书使用 DER 表示序列化,旨在消除编码选项。 DER 的目的是在每个可表示值和可以传输的位向量之间创建一对一映射。 DER 的某些方面很难(如果不是不可能的话)用上下文无关文法来编写,首先是要求可变长度位向量在其长度之前。更复杂的是传输 SET-OF 组合的 DER 要求:SET-OF 中的元素必须单独编码,然后按字典位顺序输出编码。

顺便说一句,DER 等规范表示的意义恰恰在于可以对序列化数据进行数字签名。

在我看来,ASN.1 是一部引人入胜但价值被低估的作品。虽然它似乎不太可能每次都享受复兴(但是,谁知道呢?),更不用说会有 ASN.2,ASN.1 设计中考虑的惊人范围的问题阐明了复杂的任务以一种可以极大地有益于其他“更简单”序列化技术的设计的方式可靠地传输序列化数据。