当前位置:   article > 正文

ASN.1、BER和DER的PKCS相关子集入门介绍_golang asn1

golang asn1

文章目录


本文翻译自Burton S. Kaliski Jr. 1993年11月1日修订的版本的RSA实验室技术笔记《A Layman’s Guide to a Subset of ASN.1, BER, and DER》,原文链接: http://luca.ntop.org/Teaching/Appunti/asn1.html

译者对自认为翻译可能不够准确的地方附上了原文,如有错误,请读者不吝评论斧正。

摘要

本笔记对 OSI 的抽象语法标记1 (Abstract Syntax Notation One,ASN.1)、基本编码规则 (Basic Encoding Rules,BER) 和可分辨编码规则 (Distinguished Encoding Rules,DER) 的子集进行入门介绍,目的是提供足够的背景知识以便让外行人都能够理解和实施 PKCS 系列标准。

1. 介绍

“软件开发管理的关键是抽象”是一个广为大众所接受的设计原则。通过抽象,设计者可以描述/定义系统的某个部分,而无需关注该部分实际是如何实现和表示的。 这种做法的优势如下:

  • 使实施保持开放;
  • 简化标准规范;
  • 便于描述该部分的“公理”,而在实现时证明、在被其他的上层模块采用时做条件假设(It makes it possible to state “axioms” about the part that can be proved when the part is implemented, and assumed when the part is employed in another, higher-level part. )。

因此,抽象是大多数现代软件标准规范的特点之一。

现今最复杂的系统之一,开放系统互联(Open System Interconnection,OSI,在X.200标准规范中描述),就涉及了大量的抽象。OSI 是一种国际标准化体系架构,用于管理计算机从物理层到应用层的互联。在OSI中,较高层抽象定义的对象旨在通过较低层的对象来实现。例如,某层的服务可能需要在计算机之间传输某些抽象对象;此时较低层可能是通过编码将抽象对象转换成01串,并为01串提供传输服务,进而实现对上层抽象对象的传输。OSI 之所以被称为开放系统是因为对各层的服务它支持多种不同的实现方式。

OSI 中用于描述/定义抽象对象的方法称为 ASN.1(Abstract Syntax Notation One,在 X.208标准规范中定义),用于将这些对象表示为 01串的一组规则称为 BER(Basic Encoding Rules,在 X.209 中定义)。 ASN.1 是一种灵活的表示法,它允许定义各种数据类型,从简单类型(如整数和位串)到结构化类型(如集合和序列)以及根据其他类型定义的复杂类型。 BER描述了如何将每个ASN.1类型的值表示或编码为一串八位组。 对于相同的ASN.1值,通常有不止一种方法可以对其进行 BER 编码。 另一组规则称为可分辨编码规则 (DER),它是 BER 的子集,能够为每个 ASN.1值提供唯一编码。

这份笔记的目的是描述ASN.1、BER和DER的一个子集,该子集涉及的内容足以让人能够理解和实现RSA Data Security公司的公钥加密标准(这是一个基于OSI的应用)。本文的内容包括 对ASN.1、BER、DER的一个概述 和 经删减的ASN.1类型及对应的BER、DER编码。本文2~4节依序给出ASN.1、BER和DER的概述,第5节罗列了一些ASN.1类型,并给出它们的符号表示、特定的编码规则、示例和本文对它们在PKCS中的应用的点评。第6节使用一个X.500可分辨名称(X.500 distinguished names)示例作为总结。

ASN.1 的高级特征(例如宏)未在本笔记中描述,因为它们不是实现 PKCS 所必需的。 有关ASN.1的其他功能的信息以及更详细的一般信息,请参阅定义 ASN.1 和 BER 的 CCITT 建议 X.208 和 X.209(译者注:截至译者翻译本文时,ASN.1的最新标准规范是X.680,BER、而DER的最新标准规范是X.690)。

术语和符号

在这份笔记中,八位组是指一个8位的无符号整数,其中的位8权重最高,位1权重最低。此外,ASN.1符号将使用到如下的记号说明:

符号含义
BIT等宽字体表示类型和值的字面意义上的字符表示; 在示例中,它通常表示十六进制的八位组值
n1粗斜体表示一个变量
[]粗方括号指示该项是可选的
{}粗花括号聚合相关项
|粗竖线分隔某个组内的备选项
粗省略号表示重复出现
=粗等号将术语用子术语表示

2. 抽象语法标记1(ASN.1)

ASN.1是用于描述抽象类型和值的一种符号表示法。

在ASN.1中,类型表示一组值的集合。某些类型具有有限数量的值,而某些其他类型具有无限多的值。给定ASN.1类型的某个值是该类型中的一个元素。ASN.1有四种类型:

  • 简单类型(simple types):ASN.1中的不可拆分的原子类型;
  • 结构类型(structured types):可拆分组件的类型;
  • 标记类型(tagged types):从其他类型派生的类型;
  • 其他类型(other types):包括 CHOICE 类型和 ANY 类型。

类型和值可以使用ASN.1的分配操作符(::=)赋予名字,这些名字进而可以用于定义其他类型和值。

除了CHOICE和ANY之外的每个类型都具有一个标签(tag),这个标签由一个类别(class)和一个非负的标签号码(a nonnegative tag number)组成。当且仅当标签号码相同的情况下,ASN.1类型在抽象意义上是相同的。换句话说,ASN.1类型的名字并不能影响其抽象含义,只有标签可以。标签有如下四个类别:

  • 通用标签(Universal): 用于在所有应用中含义均相同的类型,这些类型只在X.208中被定义。
  • 应用标签(Application):用于含义特定于某个应用的类型,例如X.500目录服务。两个不同的应用中的类型 可能具有相同的应用特定标签(application-specific tag)但是含义却不同。
  • 私有标签:(Private):用于对某个实体来说含义特定的类型。
  • 上下文标签(Context-specific):用于在给定的结构类型中含义特定的类型。上下文特定标签用于在给定结构类型中区分具有相同基础标签号码的组件类型,以及在两个不同的结构类型中区分在两个具有相同的标签和不同含义的组件类型。

X.208定义了带通用标签的类型,并给出了这些类型的通用标签号码(universal tag number)。带其他标签的类型在很多地方定义,并且通常通过隐式或者显式的标签获得(参见2.3节)。表1列出了一些ASN.1类型以及它们的通用类标签。

Type(类型)Tag number (十进制表示的标签号码)Tag number (十六进制表示的标签号码)
INTEGER202
BIT STRING303
OCTET STRING404
NULL505
OBJECT IDENTIFIER606
SEQUENCESEQUENCE OF1610
SETSET OF1711
PrintableString1913
T61String2014
IA5String2216
UTCTime2317

Table 1. 一些类型以及它们的通用类标签号码

ASN.1 类型和值用一种灵活的、类似于编程语言的符号来表示,其具有如下的特殊规则:

  • 布局并不重要,多空格以及换行可视为单空格
  • 注释使用成对出现的连字符对 (–) ,或者使用一个连字符对和一个换行符。
  • 标识符(Identifiers,值和域的名字)和类型引用(type reference,类型的名字)由大小写字母、数字、连字符、和空格组成,标志符使用小写字母开头,类型引用使用大写字母开头。

下文分四个小节分别概述简单类型、结构类型、隐式及显式标记类型和其他类型,第5节将更具体地描述具体的类型。

2.1 简单类型

简单类型是那些不包含组件的类型; 它们是“原子”类型。 ASN.1 所定义的类型中与 PKCS 标准相关的如下:

  • BIT STRING:一个任意的由0和1构成的位串
  • IA5String:一个任意的IA5(ASCII)字符串
  • Integer:一个任意的整数
  • NULL:一个空值
  • OBJECT IDENTIFIER:一个对象标志符,它是一个整数序列,用于识别一个对象,如某个算法或者某个属性类型。
  • OCTET STRING:一个任意的八位组(八位的值)串
  • PrintableString:一个任意的可打印字符串
  • T61String:一个任意的T.61(八位)字符串
  • UTCTime:一个协调世界时间或者格林威治标准时间(GMT)值

简单类型整体上可划分为两个大类:string类型和非String类型。BIT STRINGIA5StringOCTET STRINGPrintableStringT61StringUTCTime均是string类型。

出于编码目的,string类型是可视为由组件构成的,其组件为字串。因此,这使得人们可以对长度无法预知的值(如从文件流中输入的八位组串)使用结构化的、不定长的编码方式。

对于string类型,可以给出大小限制,以限制值的长度。

2.2 结构类型

结构类型是由组件构成的类型。ASN.1定义了4种结构类型(都与PKCS标准相关):

  • SEQUENCE:由一种或者多种类型组成的有序集合;
  • SEQUENCE OF:由给定类型的一次或者多次出现构成的有序集合;
  • SET:一个一种或者多种类型构成的无序集合;
  • SET OF:由给定类型的一次或者多次出现构成的无序集合。

结构类型可以包含可选组件,这些可选组件可能具有默认值。

2.3 隐式或者显式标记类型

标记有利于在某个应用内进行类型区分;它也常用在某个结构类型中,用以区分组件类型。例如SET或者SEQUENCE类型中的可选组件通常会被赋予不同的上下文标签(context-specific tag)来避免混淆。

有两种标记一个类型的方式:隐式或者显式。

  • 隐式标记类型是通过改变其基础类型标签来从其他类型中导出的类型(原文:Implicitly tagged types are derived from other types by changing the tag of the underlying type.)。隐式标记用ASN.1关键词[class number] IMPLICIT 指示(见5.1节)。

  • 显式标记类型是通过给其基础类型标签添加一个外层标签来从其他类型中导出的类型(原文:Explicitly tagged types are derived from other types by adding an outer tag to the underlying type.)。在最终效果上,直接标记类型是由一个组件,即基础类型,构成的结构类型。直接标记用ASN.1关键词[class number] EXPLICIT指示(见5.2节) 。

关键词[class number]本身与显式标记一样,除了当ASN.1类型定义所在的模块(module,“模块”)默认使用隐式标记的情况之外。(模块是本笔记所未涉及的高级特征。)

出于编码目的,隐式标记的类型除了标签不一样之外,被认为与其基础类型相同;显式标记类型被认为是只含一个组件(即其基础类型)的结构类型。隐式标签可以使得编码长度更短,但是在其基础类型不确定(如,基础类型是CHOICEANY)这种需要避免混淆的场景下显式标签是必需的。

2.4 其他类型

ASN.1中其他类型包括CHOICEANY两种类型。CHOICE类型表示具有一个或者多个备选项的一个联合体(union);ANY类型表示一个任意的值或者任意类型,这里所说的任意类型可能在一个对象标识符或者整型值的注册阶段被定义。

3. 基本编码规则(BER)

ASN.1的BER给出一种或者多种方法将ASN.1值表示为一个八位组串。(当然,也有其他的方式来表示ASN.1 值,但BER是OSI中用于交换这些ASN.1值的标准。)

在BER下,有三种方法可以用于编码ASN.1值,对方法的选择取决于值的类型以及值的长度是否可以预知。这三种方法分别是:

  • 原始的定长的编码方法;
  • 结构化的定长的编码方法;
  • 以及结构化的非定长的编码方法。

简单的非string类型使用原始的定长编码方法;结构类型使用任一种结构化的编码方法;简单的string类型可以根据值长度是否已知使用上述任一种编码方法。

由隐式标记导出的类型使用其基础类型的编码方法;由显式标记导出的类型使用结构化的编码方法。

在每种方法中,BER编码三个或者四个部分:

  • 标识符八位组(Identifier octets):这部分区分ASN.1值的类别和标签号码(class and tag number),并指示使用的编码方法是原始的还是结构化的。
  • 长度八位组(Length octets):
    • 对于定长编码方法,这部分给出内容八位组(content octets)的字节数量;
    • 对于结构化非定长编码方法,这部分用于指示内容八位组的字节数量是不确定的。
  • 内容八位组(Content octets):
    • 对于原始的定长编码方法,这给出值的一个实质表示;
    • 对于结构化的编码方法,这给出其组件值的BER编码值的一个串联结果。
  • 结束标志八位组(End-of-content octets):对于结构化的非定长的方法,这部分知识内容字段的结束。对于其他的编码方法,这个字段是不存在的。

上述的三种编码方式将在以下的章节中描述。

3.1 原始的定长的编码方法

这种方法应用于简单类型以及由隐式标记从简单类型导出的类型。这种编码方法要求值的长度是可以预先得知的。这部分的BER编码如下:

标志符八位组(Identifier octets):分两种情况:低标签号码(对于从0~30的号码值)和高标签号码值(对于31或者更大的标签号码值)。

  • 低标签号码编码:占一个八位组。位8 和 位7 指定标签类别,位6的值为“0”,指示使用的是原始编码方法,位5-1给出标签号码。

    ClassBit 8Bit 7
    通用标签(universal)00
    应用标签(application)01
    上下文标签(context-specific)10
    私有标签(private)11

    Table 2. 标志符八位组中的标签类别编码

  • 高标签号码编码:占两个或者更多八位组。第一个八位组除了位5-1全取值为“1”之外,使用低标签号码编码形式。第二个以及随后的八位组给出以128为基的标签号码,首先是权重最高的数字,接着是尽可能少的数字,这些八位组除了最后一个之外其他的八位组的位8均取值为“1”。

长度八位组(Length octets):分两种情况:短长度(对于从0~127的长度)以及长长度(对于0~2^1008-1之间的长度)。

  • 短长度编码:占一个八位组。位8取值为“0”,位7-1给出长度值;
  • 长长度编码:占2~127个八位组。第一个八位组的位8取值为“1”,位7-1给出给出随后的长度八位组的数量。第二以及随后的八位组给出长度值(以256为基),其中权重最高的数字有限。

内容八位组(content octets):这部分给出值(或者基础类型的值,如果该类型是由隐式标记推导出来的的话)的具体表示。特定类型的细节将在后面的第5节给出。

3.2 结构化的定长的编码方法

这种方法应用于简单的string类型、结构类型、由隐式标记从简单string类型及结构类型导出的类型、由显式标记从任意类型导出的类型。这种编码方法要求值长度是可以预先得知的。这部分的BER编码如下:

标志符八位组:同3.1节,除位6取值为“1”用以指示使用的是结构化的编码;

长度八位组:同3.1节;

内容八位组:组件值的BER编码的级联:

  • 对于简单string类型以及由隐式标记从它们导出的类型,是值(对于隐式标记则是底层值)包含的连续子串的BER编码的级联
  • 对于结构类型以及由隐式标记从它们导出的类型,是值(对于隐式标记则是底层值)包含的组件的BER编码的级联
  • 对于由显式标记从任意类型导出的类型,是底层值的BER编码。

特定类型的细节将在第5节给出。

3.3 结构化的非定长的编码方法

这种方法用于简单的string类型、结构类型、由隐式标记从简单string类型和结构类型导出的类型、由显式标记从任何类型导出的类型。这种方法不需要预先知道值的长度。这部分的编码如下:

标志符八位组:同3.2节;

长度八位组:占一个八位组,取值为80

内容八位组:同3.2节;

结束标志八位组(End-of-content octets):占两个字节00 00;

鉴于内容结束标志八位组可能出现在一个预期是正常BER编码的地方(如sequence value的内容八位组中),即0000分别是标识符和长度八位组,因而内容结束标志八位组实际上是一个带通用类别、标签号码为0、长度为0的值的原始定长编码。

4. 可分辨编码规则 (DER)

ASN.1 的可分辨编码规则(Distinguished Encoding Rules,DER)是 BER 的一个子集,它只提供了一种将ASN.1 值表示为八位组串的方法,适用于要求唯一编码的应用场景,如需要在 ASN.1 值上计算数字签名的情况。 DER 在 X.509 的第 8.7 节中定义。

DER在第3节的基础上添加了如下约束:

  1. 当长度在0~127之间时,必需使用短长度编码;
  2. 当长度大于或等于128时,必需使用长长度编码,且必需编码为数量最少的八位组,也就是说能用2个八位组编码完的不能用3个或者更多;
  3. 对于简单string类型 或者 由隐式标记从简单string类型导出的类型,必需使用原始的、定长的编码方法;
  4. 对于结构类型、从结构类型导出的隐式标记类型和从任何类型导出的显式标记类型,必需使用结构的、定长的编码方法。

其他对特定类型(例如BIT STRINGSEQUENCESETSET OF)的约束将在第五节被定义。

5. 部分类型的表示法与编码

本节给出了一些 ASN.1 类型的表示法,并描述了如何使用 BER 和 DER 对这些类型的值进行编码。

本节所述的类型即在第2节所展示的类型,本节将按字母序依次对它们进行介绍。

每部分的描述覆盖所述类型的ASN.1表示法、BER编码和DER编码。编码描述的重点将放在内容八位组的编码上,标签(tag)和长度八位组的编码遵循第3和第4节所述的规则。下文也解释了每种类型在 PKCS 和相关标准中的使用位置。 ASN.1 表示法通常仅用于类型,但对于 OBJECT IDENTIFIER 类型,也给出了值表示法。

5.1 隐式标记类型(Implicitly taggged types)

隐式标记类型 是 通过改变基础类型标签 从其他类型导出的类型。

隐式标记被用在PCKS全文里SEQUENCE中的基础类型是非ANY类型的可选组件上,以及在PKCS #7中ExtendedCertificateOrCertificate类型的extendedCertificate备选项上。

5.1.1 ASN.1 表示

[[class]number] IMPLICIT Type

class=UNIVERSAL|APPLICATION|PRIVATE

这里的Type表示类型,class是一个可选的标签类别,number是在该类别内的标签号码,是一个非负的整数。

在默认标记方法为隐式标记的ASN.1“模块”中,表示法[[class]number] Type也是可接受的,这里隐含了IMPLICIT关键词。(见2.3节)对于在模块外部声明的定义,推荐明确包含关键字 IMPLICIT 以防造成歧义。

如果类别名称缺失,则该标签是上下文类标签。上下文标签仅允许出现在结构类型或者SET类型的组件上。

例如:PKCS #8的PrivateKeyInfo类型包含一个可选的attribute组件,该组件的标签是隐式上下文类的。

PrivateKeyInfo ::= SEQUENCE {
  version Version,
  privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
  privateKey PrivateKey,
  attributes [0] IMPLICIT Attributes OPTIONAL }
  • 1
  • 2
  • 3
  • 4
  • 5

这里attributes基础类型是Attributesclass缺失(也就是说,它的标签是上下文类的),在该标签类别中,其标签号码为0。

5.1.2 BER编码

根据基础类型的不同使用原始的或结构化的编码,内容八位组与其底层值经BER编码后的结果相同。

例如:某个PrivateKeyInfo值中的attribute组件的BER编码如下:

  • 如果底层Attributes值使用的是原始的BER编码,则标识符八位组取值为80;如果底层Attributes值使用的是结构化的BER编码,则取值为A0;
  • 长度和内容八位组就是底层Attributes值的长度和内容值经BER编码后的八位组。
5.1.3 DER编码

根据基础类型的不同使用原始的或结构化的编码。内容八位组与其底层值经DER编码后的结果一致。

5.2 显式标记类型(Explicitly tagged types)

显式标记类型 是指 通过给基础类型添加一个外层的标签 来从其他类型导出的类型。

显式标记被用在PKCS全文里SEQUENCE中除ANY之外的类型的可选组件上,以及在X.509的Certificate类型中的version组件上。

5.2.1 ASN.1表示

[[class]number] EXPLICIT Type

class=UNIVERSAL|APPLICATION|PRIVATE

这里的Type表示类型,class是一个可选的标签类别,number是在该类别内的标签号码,是一个非负的整数。

如果类别名称缺失,则该标签是上下文类标签。上下文标签仅允许出现在SEQUENCESET或者CHOICE类型的组件上。

在默认标记方法是显式标记的ASN.1“模块”中,表示法[[class]number] Type也是可接受的,这里隐含了EXPLICIT关键词。(见2.3节)对于在模块外部声明的定义,推荐明确包含关键字 EXPLICIT 以防造成歧义。

例1:PKCS #7的ContentInfo类型中包含一个可选的content组件,该组件的标签是显式上下文类的:

ContentInfo ::= SEQUENCE {
  contentType ContentType,
  content
    [0] EXPLICIT ANY DEFINED BY contentType OPTIONAL }
  • 1
  • 2
  • 3
  • 4

这里,基础类型是ANY DEFINED BY contentType,标签类别class缺失(即,它是上下文类型的),在该标签类别中,此类型的标签号码是0。

例2:X.509中Certificate类型中包含一个带显式上下文类标签的version组件,它的EXPLICIT关键词被省略:

Certificate ::= ...
  version [0] Version DEFAULT v1988,
...
  • 1
  • 2
  • 3

上述Version类型的标签是显式的,因为X.509中定义了Certificate类型的ASN.1“模块”的默认标记方法是显式标记。

5.2.2 BER编码

使用的是结构化的编码方法。内容八位组是经BER编码的底层值。

例如:对某个ContentInfo类型值中content组件的编码为:

  • 标识符八位组:A0
  • 长度八位组表示底层ANY DEFINED BY contentType值经BER编码后的结果的长度
  • 内容八位组为底层ANY DEFINED BY contentType值经BER编码后的结果
5.2.3 DER编码

使用的是结构化的编码。内容八位组是底层值经DER编码后的结果。

5.3 ANY

ANY类型表示任意某个类型的任意某个值,其中具体的类型可能在对象标识符或者某个关联的整数索引被注册时定义。

ANY类型出现在PKCS #7 ContentInfo类型中代表某个特定的content类型的内容,在X.509 AlgorithmIdentifier类型中代表某个特定的算法的参数,在X.501 AttributeAttributeValueAssertion类型中代表属性值。 Attribute类型在PKCS #6,#7,#8,#9 和 #10被用到,而AttributeValueAssertion类型在X.501 的可分辨名称中被用到。

5.3.1 ASN.1表示

ANY [DEFINED BY identifier]

这里的identifier是一个可选的标识符。在使用ANY形式时,实际的类型是不确定的。

ANY DEFINED BY identifier 这种形式只能出现在SEQUENCESET类型的某个组件内,其中identifier 是这个SEQUENCESET类型中的其他组件,其类型是INTERGEROBJECT IDENTIFIER或者由这两者之一导出的标记类型。在这种形式下,ANY所代表的实际类型 要么是对象标识符值注册时,要么是在列表中的整数值注册时 由其他组件的值确定。

例如:X.509的AlgorithmIdentifier类型定义了一个ANY类型的组件:

AlgorithmIdentifier ::= SEQUENCE {
  algorithm OBJECT IDENTIFIER,
  parameters ANY DEFINED BY algorithm OPTIONAL }
  • 1
  • 2
  • 3

这里,parameter组件的实际类型取决于algorithm组件的值,实际的类型将在注册algorithm组件对应的对象标识符值时被定义。

5.3.2 BER 编码

与实际值的BER编码一致。

例如parameter组件的值的BER编码 即为 algorithm组件对应的对象标识符的注册值所定义的实际类型的值的BER编码。

5.3.3 DER编码

与实际值的BER编码一致。

5.4 BIT STRING

BIT STRING 类型表示一个任意的0和1构成的位串。一个BIT STRING值可以是任意长度的,包括0。这个类型是一个string类型。

BIT STRING类型被用在PKCS #6 ExtendedCertificate类型extendedCertificate所包含的数字签名、X.509 Certificate类型certificate所包含的数字签名和X.509 SubjectPublicKeyInfo类型所包含的公钥上。

5.4.1 ASN.1 表示

BIT STRING

例如:X.509 SubjectPublicKeyInfo类型中包含了一个BIT STRING类型的组件:

SubjectPublicKeyInfo ::= SEQUENCE {
  algorithm AlgorithmIdentifier,
  publicKey BIT STRING }
  • 1
  • 2
  • 3
5.4.2 BER 编码

BIT STRING使用原始的或者结构化的编码。

在使用原始的编码的情况下,第一个内容八位组给出该串的实际位长度要凑成8的倍数所欠缺的位数量(亦即,未使用的位的数量);而后续的八位组给出被转换成八位组串的位串值。转换过程如下:

  1. 如果该位串的位长度除8之后的余数在1~7之间,那么位串末尾将被填充任意位值直至填充后的串长度是8的倍数。如果位串的位长度已经是8的整数倍,那么无需填充。
  2. 填充后的位串被划分为八位组。填充后的位串的前8位(位8到位1)变成第一个八位组,依次类推,直到最后的8位。

在使用结构化的编码的情况下,内容八位组给出位串所包含的子串的BER编码的级联,其中除了最后一个子串之外,每个子串的长度都必需是8位的整数倍。

例如:根据填充的位值、长度编码和编码方式(原始的或结构化的)的不同选择,BIT STRING值“0110 1110 0101 1101 11”的BER编码可以如下的任一种:

  1. DER编码:
03 04 06 6e 5d c0
  • 1
  1. 用 "100000"填充:
03 04 06 6e 5d e0
  • 1
  1. 使用长长度编码方式:
03 81 04 06 6e 5d c0
  • 1
  1. 结构化编码"0110111001011101" + “11”:
23 09        
   03 03 00 6e 5d
   03 02 06 c0
  • 1
  • 2
  • 3
5.4.3 DER编码

使用原始的编码方式,除了位串填充值是0值之外,内容八位组跟原始BER编码是一样的。

例如:BIT STRING值“0110 1110 0101 1101 11”的DER编码为:

03 04 06 6e 5d c0
  • 1

5.5 CHOICE

CHOICE类型表示一个或者多个备选项的联合。

在PKCS #7 ExtendedCertificateOrCertificate类型中,CHOICE类型被用于表示一个扩展证书和一个X.509证书构成的联合。

5.5.1 ASN.1 表示

CHOICE {
[identifier1] Type1,
…,

[identifier_n] Typen }

其中,identifier1,…,identifiern 是可选的(不同的备选项使用不同的标识符identifier),Type1,…,Typen是可供选择的备选类型。标识符主要用于文档;它们不会以任何方式影响类型的值或其编码。

联合中的类型必需具备不同的标签,这个要求通常可以通过对某些备选项添加显式或者隐式标记得到满足。

例如:PKCS #7中ExtendedCertificateOrCertificate类型是一个联合类型:

ExtendedCertificateOrCertificate ::= CHOICE {
  certificate Certificate, -- X.509
  extendedCertificate [0] IMPLICIT ExtendedCertificate
}
  • 1
  • 2
  • 3
  • 4

这里备选项的标识符分别是certificateextendedCertificate,备选项的类型则是Certificate[0] IMPLICIT ExtendedCertificate

5.5.2 BER 编码

与被选择的备选项的BER编码一致。备选项具备不同的标签 使得 可以将它们的BER编码区分开。。

例如:如果被选择的是certificate,其标识符八位组的BER编码为30;如果被选择的extendedCertificate,其标识符八位组的编码为A0

5.5.3 DER编码

与被选择的备选项的DER编码一致。

5.6 IAS5tring

IA5String类型表示由IA5字符构成的任意字符串。IA5 代表 International Alphabet 5,与 ASCII 相同。 字符集包括无法打印的控制字符。 IA5String 值的长度可以是任何值,包括零。 该类型是string类型。

IA5String类型被用在PKCS #9 电子邮箱地址、无结构名字和无结构地址属性中。

5.6.1 ASN.1表示

IA5String

5.6.2 BER编码

这种类型可以使用原始的或者结构的编码。在原始编码中,内容八位组给出IA5字符串所包含经ACSII编码的字符;在结构化编码中,内容八位组给出IA5字符串的连续子串的BER编码的级联。

例如:根据长度编码和编码方式(原始的或结构化的)的选择的不同,IA5String类型值“test1@rsa.com"的BER编码可以是如下的任何一种:

  1. DER编码:
16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d
  • 1
  1. 使用长长度编码方式:
16 81 0d
   74 65 73 74 31 40 72 73 61 2e 63 6f 6d
  • 1
  • 2
  1. 结构化编码"test1" + “@” + “rsa.com”:
36 13
   16 05 74 65 73 74 31
   16 01 40
   16 07 72 73 61 2e 63 6f 6d
  • 1
  • 2
  • 3
  • 4
5.6.3 DER编码

使用原始的编码方式。内容八位组即为使用原始BER编码的结果。

例如:IA5String值"test1@rsa.com"的DER编码为:

16 0d 74 65 73 74 31 40 72 73 61 2e 63 6f 6d
  • 1

5.7 INTERGER

INTERGER表示一个任意的整数。INTERGER的值可以是正数、负数或者零,并可以是任何量级。

INTERGER在PKCS中被用于指示版本号(version number),在PKCS #1 的RSAPublicKeyRSAPrivateKey类型 以及 PKCS #3的DHParameter类型中指示模值、指数和素数之类的密码学参数,在PKCS #5的PBEParameter类型中指示一个消息摘要的迭代次数,在X.509 Certificate类型中指示版本号和序列号。

5.7.1 ASN.1 表示

INTEGER [{ identifier1(value1)identifiern(valuen) }]

这里identifier1,…,identifiern是可选的互不相同的识别码,value1,…,valuen是可选的整数值。识别符如果存在的话,它是与该整数值相关联的。

例如:X.509的Version类型是一个带有识别码的INTERGER类型:

Version ::= INTEGER { v1988(0) }
  • 1

识别码v1988与值0关联。X.509 Certificate类型使用识别码v1988来给version组件赋予一个默认值0:

Certificate ::= ...
  version Version DEFAULT v1988,
...
  • 1
  • 2
  • 3
5.7.2 BER编码

使用原始的编码方式。内容八位组给出以256为基、权重最高的数字优先、补码形式的整数值,并将该整数值编码为数量最少的八位组。0值编码为单个00八位组。

下表为一些INTERGER类型值的BER编码(DER编码也是一样)的示例:

整数值经BER编码的结果
002 01 00
12702 01 7F
12802 02 00 80
25602 02 01 00
-12802 01 80
-12902 02 FF 7F

表3. 示例整数值的BER编码

5.7.3 DER编码

使用原始的编码方式,内容八位组的编码即为使用原始方式对该整数值进行BER编码的结果。

5.8 NULL

NULL 表示一个空值,被应用于PKCS的好些地方来用于指示算法参数。

5.8.1 ASN.1 表示

NULL

5.8.2 BER 编码

使用原始的编码方式,其内容八位组为空。

示例NULL值的编码方式可以使用如下的任一种,取决于长度编码的方式:

05 00
05 81 00
  • 1
  • 2
5.8.3 DER 编码

使用原始的编码方式,内容八位组为空,一个NULL值的编码总是05 00

5.9 OBJECT IDENTIFIER

OBJECT IDENTIFIER类型用于指示一个对象标识符,它是一个整数序列,用于识别一个对象,如某个算法、某个属性类型、或者定义了某个对象标识符的注册机构。OBJECT IDENTIFIER的值可以包含任意数量的整数,这些整数可以是任意的非负值。该类型为非string类型。

IBJECT IDENTIFIER值的具体含义由注册机构赋予。各注册机构需对以给定序列开头的所有整数序列负责。某个注册机构通常将其域下的序列子集或者特定的对象类型授权给其他的注册机构。每个对象标识符至少包含两个整数。

OBJECT IDENTIFIER在PKCS #7 ContentInfo类型中用于识别内容,在X.509 AlgorithmIdentifier类型中用于识别算法,在X.501 AttributeAttributeValueAssertion类型中用于识别属性。Attribute类型在PKCS #6、#7、#9和#10中均有被用到,AttributeValueAssertion类型则被用在X.501的可分辨名称中。OBJECT IDENTIFIER的相关值在PKCS全文中被定义。

5.9.1 ASN.1 表示

符号:OBJECT IDENTIFIER

值的组成结构:

{ [identifier] component1 … componentn }

componenti = identifieri | identifieri (valuei) | valuei

其中 identifier, identifier1, …, identifiern 为识别码, value1, …, valuen 是可选的整数值。

没有识别码的形式是展示其所有组件的完整值形式;带识别码的形式则是用识别码缩略了其以另一个对象标识符值作为开始的部分。识别码 identifier, identifier1, …, identifiern主要用于文档说明,当识别码与整数值都存在的情况下,识别码必须与整数值对应。仅当这些标识符属于X.208 所定义的一小组标识符时,它们才能在没有整数值的情况下出现。

例如:如下的两组值均表示分配给RSA Data Security公司的同一对象标识符:

{ iso(1) member-body(2) 840 113549 }
{ 1 2 840 113549 }
  • 1
  • 2

需要注意,在这个给出ASN.1 值表示法的示例中,对象标识符值是十进制数据而非十六进制。表4给出一些其他的对象标识符的值以及含义。

Object identifier valueMeaning
{1 2}ISO member bodies
{ 1 2 840 }US (ANSI)
{ 1 2 840 113549 }RSA Data Security, Inc.
{ 1 2 840 113549 1 }RSA Data Security, Inc. PKCS
{ 2 5 }directory services (X.500)
{ 2 5 8 }directory services-algorithms

表4. 一些对象标识符值及其含义

5.9.2 BER编码

使用原始的编码方式,其内容八位组编码方式如下,其中value1,…, valuen表示对象标识符完整值形式中的各组件的整数值:

  1. 第一个八位组的值为 40 * value1 + value2。(这是无歧义的,因为value1被限制只能取0、1或2,而在value1取值为0或者1时value2的取值范围只能是0~39;而且根据X.208,n至少应为2);
  2. 后续如果还有其他的八位组的话,则继续编码value3,…,valuen:各个值均以128为基进行编码,权重最高的数字优先,并编码为尽量少的数字,而且除了最后一个数字之外,其余数字的最高位(位8)需置1。

例如:RSA Data Security, Inc对象标识符的第一个八位组的BER编码为 40 * 1 + 2 = 42 = 2a;840 = 6(06) * 128 + 72(48),因而840的编码为86 48;113549 = 6(06) * 128^2 + 119(77) * 128 + 13(0d),因此113549的编码为86 f7 0d。因而,该对象标识符的完整BER编码为:

06 06 2a 86 48 86 f7 0d
  • 1
5.9.3 DER编码

使用原始的编码方式,内容八位组的编码即为使用原始方式对该对象标识符值进行BER编码的结果。

5.10 OCTET STRING

OCTET STRING类型表示一个任意的八位组字符串。OCTET STRING 的值可以是任意长度的,包括0。该类型是string类型。

OCTET STRING类型在PKCS #5 PBEParameter类型中表示盐值,在PKCS #7 中表示消息摘要、信息密文摘要和加密的内容,在PKCS #8中表示私钥和加密的私钥。

5.10.1 ASN.1 表示

OCTET STRING [SIZE ({size | size1…size2})]

其中size,size1,size2是可选的长度约束。OCTET STRING SIZE(size)所定义的八位组串中,串的长度必须是size个八位组。OCTET STRING SIZE(size1…size2)所定义的八位组串中,串所包含的八位组数量必须在size1size2之间。OCTET STRING定义的八位组串中,字符串可以是任意长度。

例如:PKCS #5 PBEParameter类型包含一个OCTET STRING类型的组件:

PBEParameter ::= SEQUENCE {
  salt OCTET STRING SIZE(8),
  iterationCount INTEGER }
  • 1
  • 2
  • 3

这里salt组件的长度总是8个字节(一个字节占8位,即有一个八位组占一个字节)。

5.10.2 BER编码

使用原始的或者结构化的编码方式。在原始编码方式中,内容八位组给出串从第一个八位组到最后一个八位组的内容值;在结构化的编码方式中,内容八位组给出该串所包含的各个子串的值的BER编码结果的级联。

例如OCTET STRING类型值01 23 45 67 89 ab cd ef的BER编码结果可以是如下两种形式中的一种,具体由所选择的长度编码形式以及使用的是原始的还是结构化的编码方式决定。

  1. DER编码
04 08 01 23 45 67 89 ab cd ef
  • 1
  1. 使用长长度编码方式
04 81 08 01 23 45 67 89 ab cd ef
  • 1
  1. 结构化编码 01 … 67 + 89 … ef
24 0c
   04 04 01 23 45 67
   04 04 89 ab cd ef
  • 1
  • 2
  • 3
5.10.3 DER编码

使用原始的编码方式,内容八位组为使用原始编码方式所得到的BER编码。

例如:OCTET STRING类型值01 23 45 67 89 ab cd ef的DER编码为:

04 08 01 23 45 67 89 ab cd ef
  • 1

5.11 PrintableString

PrintableString表示由如下字符集所包含的可打印字符所构成的任意字符串:

A, B, ..., Z
a, b, ..., z
0, 1, ..., 9
(space) ' ( ) + , - . / : = ?
  • 1
  • 2
  • 3
  • 4

该类型是一个string类型。

PrintableString在PKCS #9用于表示挑战码密码与无结构地址属性以及几个X.521可分辨名称属性。

5.11.1 ASN.1 表示

PrintableString

5.11.2 BER 编码

使用原始的或结构化的编码方式。在使用原始编码方式的情况下,内容八位组给出可打印字符串中所包含的、使用ASCII编码的字符;在使用结构化编码的情况下,内容八位组给出字符串所包含的连续子串的BER编码的级联结果。

例如:根据所使用的长度编码方法和所采取的编码方式的不同,PrintableString值“Test User 1”的BER编码结果可能如下:

  1. DER编码
13 0b 54 65 73 74 20 55 73 65 72 20 31
  • 1
  1. 使用长长度编码方式
13 81 0b
54 65 73 74 20 55 73 65 72 20 31
  • 1
  • 2
  1. 结构化编码“Test ” + “User 1”
33 0f
   13 05 54 65 73 74 20
   13 06 55 73 65 72 20 31
  • 1
  • 2
  • 3
5.11.3 DER 编码

使用原始的编码方式,内容八位组即为使用原始编码方式的BER编码结果。

例如PrintableString值“Test User 1”的DER编码结果如下:

13 0b 54 65 73 74 20 55 73 65 72 20 31
  • 1

5.12 SEQUENCE

SEQUENCE类型表示一个或者多个类型的有序集合。

SEQUENCE类型的使用贯穿PKCS及与之相关的标准规范。

5.12.1 ASN.1 表示

SEQUENCE {

[identifier1] Type1 [{ OPTIONAL | DEFAULT value1}],
…,

[identifiern] Typen [{ OPTIONAL | DEFAULT valuen}]

}

其中,identifier1,…,identifiern是可选的、互不相同的组件识别码,Type1, …,Typen是组件的类型,value1,…,valuen是可选的组件默认值。识别码主要用于文档,它们无法以任何形式影响类型的值或者其编码。

OPTIONAL修饰词指示该组件值是可选的,即,不是必需要出现在序列中的。DEFAULT修饰词指示该组件值也是可选的,不过如果该组件缺失的话,该组件被赋予指定的默认值。

SEQUENCE中带OPTIONAL或者DEFAULT修饰词的连续组件,以及在前述组件之后的任何组件,它们的标签必需不同。这个需求通常可以通过在某些组件上添加显式或者隐式标记来满足。

例如:X.509 Validity类型是一个包含两个组件的SEQUENCE类型:

Validity ::= SEQUENCE {
  start UTCTime,
  end UTCTime }
  • 1
  • 2
  • 3

这里,两个组件的识别码分别为start和end,类型都是UTCTime

5.12.2 BER编码

使用结构化的编码方式。内容八位组是序列中的组件值的BER编码的按序级联,对于带OPTIONALDEFAULT修饰词的组件,其编码规则如下:

  • 如果序列中带OPTIONALDEFAULT修饰词的组件的值缺失,则该组件的编码不会被包含在内容八位组中;
  • 如果带DEFAULT修饰词的组件的值是默认值,那么该组件的编码是否被包含在内容八位组中均可。
5.12.3 DER编码

使用结构化的编码方式,内容八位组同BER编码,除了如果带DEFAULT修饰词的组件的值取值为默认值的情况下,内容八位组不会包含该组件的编码。

5.13 SEQUENCE OF

SEQUENCE OF表示由一个给定类型的0次或者多次出现构成的有序序列。

SEUQENCE OF类型被使用在X.501 可分辨名称(distinguished names)中。

5.13.1 ASN.1 表示

SEQUENCE OF Type

上述的Type是一个类型。

例如:X.501 RDNSequence类型包含RelativeDistinguishedName类型的0次或者多次出现,最重要的优先出现。

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
  • 1
5.13.2 BER编码

使用结构化的编码方式,内容八位组是集合中所多次出现的类型的值的BER编码的按序级联。

5.13.3 DER编码

使用结构化的编码方式,内容八位组是集合中所动词出现的类型的值的DER编码的按序级联。

5.14 SET

SET 类型表示一个或者多个类型的无序集合。

SET类型未被使用于PKCS。

5.14.1 ASN.1 表示

SET {
[identifier1] Type1 [{ OPTIONAL | DEFAULT value1}],
…,
[identifiern] Typen [{
OPTIONAL | DEFAULT valuen}]}

其中,identifier1,…,identifiern是可选的、互不相同的组件识别码,Type1, …,Typen是组件的类型,value1,…,valuen是可选的组件默认值。识别码主要用于文档,它们无法以任何形式影响类型的值或者其编码。

OPTIONAL修饰词指示该组件值是可选的,即,不是必需要出现在集合中的。DEFAULT修饰词指示该组件值也是可选的,不过如果该组件缺失的话,该组件被赋予指定的默认值。

集合中的组件的标签必需互不相同,这个需求通常可以通过给某些组件赋予显示或者隐式标记实现。

5.14.2 BER编码

使用结构化的编码方法。内容八位组是集合中的组件的值的BER编码 按照任意顺序的级联,其中带OPTIONALDEFAULT修饰词的组件的编码规则如下:

  • 如果集合中带OPTIONAL或者DEFAULT修饰词的组件的值缺失,那么该组件的编码不会出现在内容八位组中。
  • 如果DEFAULT修饰的组件的值取值为默认值,则该组件的编码可以出现也可以不出现在内容八位组中。
5.14.3 DER编码

使用结构化的编码方式。内容八位组与BER编码相同,除了如下两种情况:

  • 如果带DEFAULT修饰词的组件取值为默认值,该组件的编码不会包含在八位组中;
  • 组件的编码按照tag的大小升序级联。

5.15 SET OF

SET OF类型表示一个给定类型的0次或者多次出现。

SET OF类型在PKCS #6,#7,#8,#9 和 #10 被用于属性集合,在PKCS #7中被用于消息摘要算法标识符、签名者信息和接受者信息集合,在X.501中被用于可分辨名称。

5.15.1 ASN.1 表示

SET OF Type

其中,Type是一个类型。

例如:X.501 RelativeDistinguishedName类型包含AttributeValueAssertion类型的0次或者多次出现,其出现顺序并不重要:

RelativeDistinguishedName ::=
  SET OF AttributeValueAssertion
  • 1
  • 2
5.15.2 BER编码

使用结构化的编码方式。内容八位组是集合中所多次出现的类型的值的BER编码的任意顺序级联。

5.15.3 DER编码

使用结构化的编码方式,内容八位组同BER编码,除了集合的各类型值的BER编码是按照编目序升序级联之外。两个不同的BER编码的编目比较流程如下:在较短的一个BER编码的最后一个八位组之后,使用比任何正常八位组值都小的假八位组值进行逻辑填充;然后从左到右扫描这两个BER 编码直至差异出现,在差异点处具有较小八位组值的BER 编码较小。

5.16 T61String

T61String表示一个由T.61字符构成的任意字符串。T.61是ASCII字符集的一个八位扩展。特殊的“转义”序列指定对后续字符值的解释,例如日语;最初的解释是拉丁语。字符集包括不可打印的控制字符。T61String 类型仅允许拉丁语和日语字符解释,并且目录名称的实现不包含控制字符 [NIST92]。T61字符串值可以具有任何长度,包括零。此类型是字符串类型。

T61String被用在PKCS #9的无结构地址和密码挑战码属性中 以及少数X.521属性中。

5.16.1 ASN.1表示

T61String

5.16.2 BER编码

使用原始的或结构化的编码方式。

  • 在使用原始编码的情况下,内容八位组给出T.61字符串中的ASCII编码的字符。
  • 在使用结构化编码的情况下,内容八位组是T.61字符串连续子串的BER编码的级联。

例如:T.61字符串“cl’es publiques”(公钥的法语表示)的BER编码结果可能如下,实际是哪一种取决于所使用的长度八位组编码方法以及编码所使用的方式是原始的还是结构化的。

  1. DER编码
14 0f
   63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73
  • 1
  • 2
  1. 长长度编码
14 81 0f
   63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73
  • 1
  • 2
  1. 结构化编码“cl’es”+" "+“publiques”
34 15
   14 05 63 6c c2 65 73
   14 01 20
   14 09 70 75 62 6c 69 71 75 65 73
  • 1
  • 2
  • 3
  • 4

八位字符c2是一个 T.61 前缀,用于给下一个字符添加重音符号 (')。

6.16.3 DER编码

使用原始的编码方式,内容八位组与使用原始方式的BER编码结果一致。

例如T61String值“cl’es publiques”的DER编码为

14 0f 63 6c c2 65 73 20 70 75 62 6c 69 71 75 65 73
  • 1

5.17 UTCTime

UTCTime 类型表示“协调世界时(coordinated universal time)”或格林威治标准时间 (Greenwich Mean Time,GMT) 值。一个UTCTime值包括 以分或秒为精度的本地时间 和 其相比于GMT时间的偏移值(表示为小时和分钟)。它使用如下的任一种时间表示格式:

YYMMDDhhmmZ
YYMMDDhhmm+hh’mm’
YYMMDDhhmm-hh’mm’
YYMMDDhhmmssZ
YYMMDDhhmmss+hh’mm’
YYMMDDhhmmss-hh’mm’

其中:

  • YY是年份的低两位数字
  • MM是月份(01~12)
  • DD表示天(01~31)
  • hh表示小时(00~23)
  • mm表示分钟(00~59)
  • ss表示秒(00~59)
  • Z只是本地时间是GMT时间,+表示本地时间比GMT时间迟,-表示本地时间比GMT时间早。
  • *hh’*是相对GMT时间的小时偏移值值绝对值
  • *mm’*是相对GMT时间的分钟偏移值绝对值

该类型是一个字符串类型。

UTCTime类型在PKCS #9签名时间属性中用于表示签名的时间,在X.509 Validity类型中表示整数的有效期。

5.17.1 ASN.1 表示

UTCTime

5.17.2 BER编码

使用原始的或结构化的编码方式。

  • 使用原始编码方式的情况下,内容八位组给出字符串中的以ASCII编码的字符;
  • 使用结构化编码方式的情况下,内容八位组给出字符串的连续子串的BER编码的级联。(由于UTCTime值很短,使用结构化的编码方式不是很有意思,但是也是允许的)

例如:当前的这句话最开始是在太平洋夏令时1991年5月6日 4:45:40pm 写下的,这个时间可以表示为如下的任一种UTCTime时间值:

  1. “910506164540-0700”
  2. “910506234540Z”

上述值的具有如下的任一种BER编码:

  1. 17 0d 39 31 30 35 30 36 32 33 34 35 34 30 5a
    
    • 1
  2. 17 11 39 31 30 35 30 36 31 36 34 35 34 30 2D 30 37 30 30
    
    • 1
5.17.3 DER编码

使用原始的编码方式。其内容八位组与使用原始方式的BER编码结果一致。

6. 示例

本节以X.501类型Name为说明对象给出一个ASN.1表示法和DER编码的例子。

6.1 抽象表示法

本节给出X.501类型Name的ASN.1表示:

Name ::= CHOICE {
  RDNSequence }

RDNSequence ::= SEQUENCE OF RelativeDistinguishedName

RelativeDistinguishedName ::=
  SET OF AttributeValueAssertion

AttributeValueAssertion ::= SEQUENCE {
   AttributeType,
   AttributeValue }

AttributeType ::= OBJECT IDENTIFIER

AttributeValue ::= ANY
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在X.500目录中,Name类型用于辨别一个对象。Name当前是包含一个可选项RDNSequenceCHOICE类型。(X.500的未来版本可能会包含更多的可选项。)

RDNSequence类型给出其从根开始的X.500目录树路径。RDNSequence是一个SEQUENCE OF类型,其包含RelativeDistinguishedName的一次或多次出现。

RelativeDistinguishedName类型为对象给出该对象相对于其父目录节点对象的唯一名称。它是一个SET OF类型,包含AttributeValueAssertion的一次或多次出现。

AttributeValueAssertion类型给相对可分辨名称的一些属性,如国家名或者一般名称,分配属性值。AttributeValueAssertion是一个包含两个组件(一个AttributeType类型和一个AttributeValue)的SEQUENCE类型。

AttributeType类型通过对象标识符区分一个属性;AttributeValue类型给出一个任意的属性值。属性值AttributeValue的实际类型由属性类型AttributeType决定。

6.2 DER编码

本节自底向上地给出Name类型值的一个DER编码示例。

本节所使用的名称是PKCS 示例[Kal93]中的Test User 1对应的名称。该名称使用如下的路径表示:

(root)
countryName=US
organizationName=Example Organization
commonName=Test User 1

上面的每一层对应一个RelativeDistinguishedName值,该值包含一个AttributeValueAssertion值,所对应的AttributeType值是等号之前的部分,AttributeValue值是等号之后的部分(一个对应于给定属性类型的可打印字符串)。

countryNameorganizationNamecommonUnitName是X.520中定义的属性类型,它们的对象标识符分别为:

attributeType OBJECT IDENTIFIER ::=
  { joint-iso-ccitt(2) ds(5) 4 }

countryName OBJECT IDENTIFIER ::= { attributeType 6 }

organizationName OBJECT IDENTIFIER ::=
  { attributeType 10 }

commonUnitName OBJECT IDENTIFIER ::=
  { attributeType 3 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
6.2.1 AttributeType

上述的三个AttributeType的值都是OCTET STRING类型,因此它们的DER编码使用原始的、定长的方法:

属性OID DER编码属性类型
06 03 55 04 06countryName
06 03 55 04 0aorganizationName
06 03 55 04 03commonName

由于OBJECT IDENTIFIER的tag是6,其标识符八位组遵循低标签号码编码方式。位8和位7的值为0,指示它是通用类型标签,位6值为0,指示使用原始的编码方式。长度八位组遵循短长度编码方式。内容八位组是由三个八位组值表示,这三个值由对象标识符包含的整数值导出:40 * 2 + 5 = 85 = 0x55;0x04;最后是0x06、0x0a(十进制表示是10)或0x03。

6.2.2 AttributeValue

上述的三个AttributeValue值均为PrintableString类型值,因此它们的编码遵从原始的定长的编码方式:

属性值DER编码属性值
13 02 55 53“US”
13 14 45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61 74 69 6f 6e“Example Organization”
13 0b 54 65 73 74 20 55 73 65 72 20 31“Test User 1”

由于PrintableString的tag number是19(十六进制表示为0x13),在0~30范围内,因此其标识符八位组遵从低标签号码编码方式。位8和位7均取值为0,指示该类型是通用类型;位6取值为0,指示使用原始的编码方式。长度编码使用短长度编码方式,内容八位组则是属性值的ASCII表示。

6.2.3 AttributeValueAssertion

上述提及的三个AttributeValueAssertion值都是SEQUENCE类型值,因此它们的DER编码遵循结构化的、定长的编码方式:

  • countryName = “US”

    30 09
       06 03 55 04 06
       13 02 55 53
    
    • 1
    • 2
    • 3
  • organizationName = “Example Organization”

    30 1b
       06 03 55 04 0a
       13 14 45 78 61 6d 70 6c 65 20 4f 72 67 61 6e 69 7a 61 74 69 6f 6e
    
    • 1
    • 2
    • 3
  • commonName = “Test User 1”

    30 12
       06 03 55 04 0b
       13 0b 54 65 73 74 20 55 73 65 72 20 31
    
    • 1
    • 2
    • 3

由于SEQUENCE的tag number是16(十六进制0x10),在0~30范围内,因此其标识符八位组遵从低标签号码编码方式。由于SEQUENCE是通用类型,因此标签八位组的位8和位7取值为0;由于使用结构化的编码方式,其位6取值为1。长度使用短长度编码方式。内容八位组则是attributeType和attributeValue组件的DER编码的拼接。

6.2.4 RelativeDistinguishedName

上述提及的三个RelativeDistinguishedName值都是SET OF类型值,因此它们的编码遵循结构化的、定长的方法:

31 0b
   30 09 ... 55 53

31 1d
   30 1b ... 6f 6e

31 14
   30 12 ... 20 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

由于SET OF的tag number是17(十六进制0x11),在0~30范围内,因此其对应的标签八位组使用低标签好吗编码方式。由于SET OF类型在通用类型行列内,标签八位组的位8和位7取值为0,由于使用的编码方式为结构化的编码方式,因此标签八位组的位6取值为1。长度八位组遵从短长度编码方式,内容八位组即为对应的AttributeValueAssertion值的DER编码,鉴于集合中只有一个值。

6.2.5 RDNSequence

由于RDNSequence类型值是SEQUENCE OF类型值,因此其DER编码遵从结构化的、定长的编码方式:

30 42
   31 0b ... 55 53
   31 1d ... 6f 6e
   31 14 ... 20 31
  • 1
  • 2
  • 3
  • 4

由于SEQUENCE OF的tag number是16(十六进制0x10),在0~30范围内,因此其标识符八位组遵从低标签号码编码方式。由于SEQUENCE是通用类型,因此标签八位组的位8和位7取值为0;由于使用结构化的编码方式,其位6取值为1。长度使用短长度编码方式。内容八位组是三个RelativeDistinguishedName值按照在ASN.1表示中的出现顺序的依次拼接。

6.2.6 Name

Name值是一个CHOICE类型值,因此其DER编码就是上述RDNSequence值的DER编码:

30 42
   31 0b
      30 09                                   
         06 03 55 04 06                       attributeType = countryName
         13 02 55 53    											attributeValue = "US"

   31 1d
      30 1b
         06 03 55 04 0a                       attributeType = organizationName
         13 14                                attributeValue = "Example Organization"
            45 78 61 6d 70 6c 65 20 4f 72 67
            67 61 6e 69 7a 61 74 69 6f 6e

   31 14
      30 12
         06 03 55 04 03                      attributeType = commonName 
         13 0b                               attributeValue = "Test User 1" 
            54 65 73 74 20 55 73 65 72 20 31
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/998369
推荐阅读
相关标签
  

闽ICP备14008679号