• rfc 5280 X.509 PKI 解析


    本文以博客园的证书为例讲解,不包含对CRL部分的翻译,如没有对第5章节以及6.3小节进行翻译

     3.2. Certification Paths and Trust

    下面简单介绍了Public-Key Infrastructure using X.509 (PKIX)技术规范的框架,主要包括:

    end entity: PKI证书的用户和/或用户系统(证书的subject)
    CA: 证书授权机构
    RA: 证书吊销机构, 可选
    CRL issuer: 生成并签名CRL的系统
    repository:存储证书和CRL的单个系统或分布式系统,同时用于分发证书和CRLs到end entities

    CA负责指明其颁发的证书的吊销状态,可以通过Online Certificate Status Protocol (OCSP)[RFC2560],CRLs或其他机制获得证书的吊销状态。通常情况下,当吊销状态由CRLs提供时,CA同时也是CRL issuer。然而CA可能负责颁发CRLs到不同的实体(entity)。

    注意一个Attribute Authority (AA)同时选择为CRL issuer颁发CRLs。

    3.1. X.509 Version 3 Certificate

    使用public key的用户需要通过加密或数字签名来机制来确信相关的private key被正确的远端所拥有(人或系统)。证书中的public key值绑定到subjects,该绑定关系通过trusted CA签名每个证书来实现。CA可能通过某些技术手段实现该功能(众所周知,通过challenge-response协议来证明证书的拥有者)。证书有一个有限的有效生命周期。由于一个证书的证书的签名和生命周期可以被客户端的证书独立校验,因此证书可以通过不可信的通讯和服务系统进行分发,以及可以被缓存到使用证书的系统中。

    1988年发布了作为X.500 directory建议的ITU-T X.500或ISO/IEC 9594-8,它们描述了标准的证书格式。1988年的版本为v1格式,1933年增加了2个字段,为v2格式。

    1993年发布了Internet Privacy Enhanced Mail (PEM) RFCs,包括基于X.509的PKI技术标准[RFC1422]。v1和v2版本的证书格式在某些特性支持上有些匮乏。更为重要的是在实际实现中证明PEM需要更多字段来携带更多信息。作为对这些需求的响应, ISO/IEC, ITU-T, 和 ANSI X9发布了X.509 v3版本的格式,v3版本相对于v2版本新增了扩展字段,特定的扩展字段由标准指定或由任何组织或社区定义。1996年发布了v3格式。

    3.2. Certification Paths and Trust

    安全服务的用户通过获取并验证证书中包含的public key来了解public key。如果使用public key的用户没有签名该证书的CA的public key的副本,名称和相关信息(如有效周期或name constraints),那么它可能需要通过其他证书来获得该public key。通常可能会使用到证书链,包括被一个CA签名的public key拥有者(end entity)的证书以及0个或多个被其他CA签名的证书,这种链被称为证书路径,证书路径出现的原因是,public key用户需要限定数目的可信的CA public keys来进行初始化。

    为了给public key用户找到证书路径,可能会用到多种方式来配置CA。对于PEM,RFC 1422定义了严格等级结构的CA,有3种类型的PEM CA:

    a) Internet Policy Registration Authority (IPRA),该机构在Internet Society下运作,作为PEM证书等级的顶级,层级为1。它仅为下一级机构颁发证书,称为PCAs。所有的证书路径从IPRA开始

    b)Policy Certification Authorities (PCAs):PCAs位于证书的层级2,每个PCA由IPRA认证。一个PCA会建立并发布它的策略状态,该策略状态与认证用户或从属CA相关。不同的PCAs用于满足不同用户的需求。如一个PCA可能支持通用的电子邮件地址,另一个PCA可能使用严格的策略来满足合法地绑定数字签名地要求

    c)Certification Authorities (CAs): 位于证书层级3,即最底层。这些层级3的证书由PCAs认证。CAs代表了特定的组织,特定的组织单位(如部门,组,项目)或特定的地理区域。

    RFC 1422还有一个名称从属规则,它要求CA仅能为名称从属于CA本身的实体颁发证书。PCA名称隐含了与PEM证书路径相关的信任(trust)。名称从属规则保证PCAs下面的CA限制在它们可以验证的下属实体中(如一个用于某个组织的CA仅能验证属于该组织名称树中的实体)。证书用户系统会机械式地校验是否遵循了名称从属规则。

    RFC 1422使用X.509 v1证书格式。X.509 v1会对相关的策略信息强加一些结构限制或限制证书的使用,这些限制包括:

    a) 自上而下的层级中,所有的证书以IPRA开始
    b) 证书从属规则限制了CA的subject的名称 (V3中由name constraints替代)
    c) 使用PCA,要求了解个体的PACs如何内置到证书链的校验逻辑中,同时需要了解个体的PCAs如何来决定一个证书链是否可接受

    使用X.509 v3时,RFC 1422中的大部分需求都可以通过扩展实现,而无需限制CA结构的使用。特别地,与证书策略相关的扩展消除了对PCAs的依赖,constraints扩展消除了对名称从属规则的依赖。因此本文支持了一个更加灵活的架构,包括:

    a) 证书路径以用户的域中的CA的public key或最高层级的public key开始。证书路径以用户的域中的CA的public key开始有一定的好处,一些场景下,本地域的可信度最高
    b) 证书的name constraint扩展可以包含对名称的限制,但该扩展不是必须的
    c) policy扩展和policy mapping扩展替代了PCA的概念,允许更大程度的自动化。应用可以依据证书的内容而非PCAs先前的内容来决定是否可以接受一个证书路径,允许自动化处理证书路径。

    X.509 v3 同样包含一个用于表示一个subject是CA或终端实体的扩展(即Basic Constraints扩展),减少了PEM对带外消息的需求。

    本标准覆盖了2种类型的证书:CA证书和终端证书。CA证书可以划分为3种:交叉证书(cross-certificates),自发证书(self-issued),自签证书(self-signed)。交叉证书的issuer和subject是不同的,交叉证书描述了2个CA之间的信任关系;自发证书的issuer和subject为相同的实体,自发证书用于支持策略或操作的修改;自签证书即自发证书,但可能会使用证书中的public key来验证数字签名,自签证书用于携带一个public key来开始证书路径。终端证书没有权限颁发证书。

    3.3. Revocation

    当颁发一个证书时,会期望证书在它的有效期间内能够正常使用,然而有多种情况可能会导致证书在有效期内失效,如在修改名称,修改subject和CA之间的关联(如员工终止在组织中的工作),或怀疑private key的有效性。在这些情况下,CA需要吊销这些证书。

    X.509定义了一种吊销证书的方式,这种方式每个CA会周期性的发布一个签名的数据结构,称为 certificate revocation list(CRL)。CRL是带时间戳的列表,该列表用于识别一个CA或CRL issuer签名的证书,且它在公共repository中免费提供。CRL使用证书的serial number来标记已经吊销的证书。当一个使用证书的系统使用证书时(用于校验远端用户的数字签名),系统不仅会校验证书的签名和有效性,而且会获取一个最近合适的CRL来校验该证书的序列号是否在CRL中。"最近合适"的意义可能会随着本地策略而改变,但通常表示最新发布的CRL。新的CRL会定期(如,小时,天,周)发布。在接收到通知后,新的表项会在下一次更新时添加进去。除非该表项出现在超出撤销证书的有效期后的正常发布的CRL中,否则该表项不能从CRL中移除。

    使用该吊销方式的好处是CRL可以使用与证书相同的方式进行分发,即可以通过不可信的服务端或不可信的传输方式进行分发。

    使用CRL吊销方法时有一个限制,即使用不可信的通讯和服务端时,吊销的粒度限制为CRL颁发周期。例如,如果当前报告了一个证书的吊销,在CRLs正常更新之前,该吊销信息不会可靠地通知到使用证书的系统,根据CRLs的发布频率,可能为一小时,一天或一周。

    使用X.509 v3证书格式时,为了方便在多供应商之间实现互操作性,需要使用X.509 v2 CRL格式,然而该版本并不依赖CRLs的发布。消息格式和在线吊销通知协议由其他PKIX标准规定。吊销通知方法可能适用于某些环境(作为X.509 CRL的替代)。吊销报告和发布吊销信息之间的延时对在线检查吊销方法来说至关重要。一旦CA接收了一个真实且有效的吊销报告,任何对在线(检查吊销)服务的请求都会正确地反映出吊销(revocation)对证书的影响(即证书是否被吊销)。然而,这些方法会施加一些安全需求:在repository不可信时,证书验证器需要确定在线验证服务的可信度。

    3.4. Operational Protocols

    需要一种协议来支持传输证书和CRLs(或状态信息)到使用证书的客户端系统,该协议需要能够传输不同含义的证书和CRL,包含能够分发基于LDAP,HTTP,FTP和X.500格式的证书和CRL。支持这些功能的协议定义在其他PKIX规范中。这些规范可能包含协议的消息格式和支持在上述环境中的操作的流程,以及定义与MIME相关的content types。

    3.5. Management Protocols

    需要使用协议来支持PKI用户和管理证书的实体之间的在线交互。如一个管理协议可能用于CA和客户端系统之间或两个交叉认证的CA之间的证书的管理。支持这些功能的管理可以可能需要支持以下功能:

    (a) 注册:这是用户首次(直接或通过RA)向CA认证自己的过程,该过程先于CA颁发证书或为该用户生成证书

    (b) 初始化:在用户系统可以安全操作之前,需要安装与存储在基础设施中某些地方的密钥具有适当关系的key materials。例如,客户端需要public key和其他trusted CA的可信信息来进行安全初始化,后续用于证书路径校验中。即,客户端需要对其密钥对进行初始化。

    (c) 认证:CA为用户的public key颁发证书并返回证书(和/或将该证书提交到repository)的过程

    (d) 密钥对恢复:可选,客户的key materials(如用户用于加密的私钥)可能会被CA或密钥备份系统备份。如果用户需要恢复这些备份的key materials(可能由于忘记密码或丢失key chain文件),可能会提供一个在线交互协议来支持恢复操作

    (e) 密钥对更新:所有的密钥对都需要定期更新,使用新的密钥对和新颁发的证书

    (f) 吊销请求:授权用户向一个CA声明一个不正常的场景并请求吊销证书

    (g) 交叉证书:两个CA之间在建立交叉证书时会交换信息。交叉证书为一个CA颁发给另一个(含用于颁发证书的签名密钥的)CA的证书。

    注意,在线协议不是实现上述功能的唯一途径,对于所有功能都有对应的线下方式实现,本标准没有强制要求使用线上协议。如当使用hardware tokens时,大部分功能都通过传输physical tokens来实现。此外,上述的一些功能可能合并为一个协议交互。特别地,注册,初始化和认证中的两个或多个功能可以合并为一个协议交互。

    PKIX系列定义了一个支持上述功能的标准消息格式的集合。在不同环境(如电子邮件,文件传输和WWW)中传输这些消息的协议定义在这些规范中。

    4. Certificate and Certificate Extensions Profile

    本章描述了可以用于促进互操作性和重用PKI的公钥证书。本章基于X.509 v3证书格式以及[X.509]中定义的标准证书扩展。ISO/IEC和ITU-T使用的1997年发行的版本为SAN.1,而本文使用的是1988 ASN.1语法,证书和标准扩展的编码格式相同。本章也定义了用于支持PKI的私钥扩展。

    应用中广泛使用证书来实现互操作性目标和运营以及安全要求。本文的目标是为有互操作性和某些限制要求的软件建立一个通用的基线。特别地,支持X.509 v3证书用于一些非正式的电子邮件,IPsec和WWW应用。

    4.1. Basic Certificate Fields

    X.509证书包含的字段如下。数字签名中,被签名的数据使用ASN.1 DER编码规则(可以使用如openssl asn1parse -in xxx.cer来查看该编码规则下的内容),该规则使用TLV格式来编码每个元素。

    Certificate  ::=  SEQUENCE  {
           tbsCertificate       TBSCertificate,
           signatureAlgorithm   AlgorithmIdentifier,
           signatureValue       BIT STRING  }
    
      TBSCertificate  ::=  SEQUENCE  {
           version         [0]  EXPLICIT Version DEFAULT v1,
           serialNumber         CertificateSerialNumber,
           signature            AlgorithmIdentifier,
           issuer               Name,
           validity             Validity,
           subject              Name,
           subjectPublicKeyInfo SubjectPublicKeyInfo,
           issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
                                -- If present, version MUST be v2 or v3
           subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
                                -- If present, version MUST be v2 or v3
           extensions      [3]  EXPLICIT Extensions OPTIONAL
                                -- If present, version MUST be v3
           }
    
      Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
    
      CertificateSerialNumber  ::=  INTEGER
    
      Validity ::= SEQUENCE {
           notBefore      Time,
           notAfter       Time }
    
      Time ::= CHOICE {
           utcTime        UTCTime,
           generalTime    GeneralizedTime }
    
      UniqueIdentifier  ::=  BIT STRING
    
      SubjectPublicKeyInfo  ::=  SEQUENCE  {
           algorithm            AlgorithmIdentifier,
           subjectPublicKey     BIT STRING  }
    
      Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
    
      Extension  ::=  SEQUENCE  {
           extnID      OBJECT IDENTIFIER,
           critical    BOOLEAN DEFAULT FALSE,
           extnValue   OCTET STRING
                       -- contains the DER encoding of an ASN.1 value
                       -- corresponding to the extension type identified
                       -- by extnID
           }

    4.1.1. Certificate Fields

    证书包含3个SEQUENCE字段(tbsCertificate,signatureAlgorithm,signatureValue)

    4.1.1.1. tbsCertificate

    该字段包含subject和issuer的名字,与subject相关的public key和有效周期,以及其他相关信息。

    4.1.1.2. signatureAlgorithm

    signatureAlgorithm字段包含了CA用来签署该证书的识别码。[RFC3279], [RFC4055]和[RFC4491]给出了支持的签名算法,但也可能采用其他签名算法。该识别码有如下ASN.1结构: 

    AlgorithmIdentifier  ::=  SEQUENCE  {
          algorithm               OBJECT IDENTIFIER,
          parameters              ANY DEFINED BY algorithm OPTIONAL  }

    algorithm表示加密算法,如博客园使用的算法如下。parameters为可选字段。该字段包含的算法必须与4.1.2.3中的一致。

    Signature Algorithm: sha256WithRSAEncryption

    4.1.1.3. signatureValue

    signatureValue包含对(ASN.1 DER编码的)tbsCertificate字段的数字签名,此时tbsCertificate作为签名函数的输入。该签名值使用BIT STRING编码。各个签名算法的细节可以参见[RFC3279], [RFC4055]和[RFC4491]。

    为了生成该签名,CA需要对tbsCertificate中的字段进行有效性判断。特别地,CA需要对证书中的public key与subject的关联性进行有效性判断。

    signatureValue位于证书的末尾,由CA签署生成

     4.1.2. TBSCertificate

    该字段包含与证书中的subject以及签署该证书的CA相关的信息。每个TBSCertificate包含subject的name以及issuer,以及与subject相关的public key,validity period,version number和serial number,有些证书可能会包含可选的唯一标识符。TBSCertificate通常会包含扩展字段(见4.2)

     4.1.2.1. Version

    该字段描述了证书的版本,当证书使用了extension,version值必须为3(值为2)。如果没有使用extension,但使用了UniqueIdentifier,version为2(值为1)或3,如果仅存在基本字段时,version可以为1,2,3。下面为3时的情况:

    Version: 3 (0x2)

    实现中应该能够处理任何版本的证书,最低限度必须能够识别version 3的证书。

     4.1.2.2. Serial Number

    CA分配给证书的serial number必须是一个正整数。CA分配的证书中的serial number必须是唯一的(使用issuer name和serial number来确定一个唯一的 证书)。serial number最大20字节。

    Serial Number:
        0a:54:02:f5:ef:9a:7a:8b:9d:ea:06:48:ae:06:74:31

    非标准的CA可能会颁发serial number为负数或0的证书,证书使用者应该妥善处理这类证书。

     4.1.2.3. Signature

    该字段包含CA用于签名证书的算法标识,该字段的值必须与signatureAlgorithm的值一致(4.1.1.2)。

     4.1.2.4. Issuer

    issuer字段表示签名并颁发证书的实体。该字段必须包含非空的DN(distinguished  name)。issuer字段为X.501格式的Name[X.501],Name定义如下:

    Name ::= CHOICE { -- only one possibility for now --
      rdnSequence  RDNSequence }
    
    RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
    
    RelativeDistinguishedName ::=
      SET SIZE (1..MAX) OF AttributeTypeAndValue
    
    AttributeTypeAndValue ::= SEQUENCE {
      type     AttributeType,
      value    AttributeValue }
    
    AttributeType ::= OBJECT IDENTIFIER
    
    AttributeValue ::= ANY -- DEFINED BY AttributeType
    
    DirectoryString ::= CHOICE {
          teletexString           TeletexString (SIZE (1..MAX)),
          printableString         PrintableString (SIZE (1..MAX)),
          universalString         UniversalString (SIZE (1..MAX)),
          utf8String              UTF8String (SIZE (1..MAX)),
          bmpString               BMPString (SIZE (1..MAX)) }

    Name包含一系列的属性以及对应的值,例如country name的值为US。AttributeValue的值由AttributeType决定,类型通常为DirectoryString。(上述表示issuer由RelativeDistinguishedName列表构成,列表元素格式为AttributeType=AttributeValue)。DirectoryString包含如下几种编码方式:PrintableString,TeletexString,BMPString,UTF8String以及UniversalString。符合本标准的CA必须使用PrintableString或UTF8String,但存在两个例外情况:当CA先前颁发的证书的issuer字段使用TeletexString, BMPString,UniversalString时,CA可以继续使用这些编码方式,用于向后兼容;当CA加入到一个使用TeletexString, BMPString, UniversalString编码的domain时,它将使用与该domain中的CAs相同的编码方式。

    Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=Encryption Everywhere DV TLS CA - G1

    如上所述,DN包含多个属性,本标准没有限制Name中的属性类型,然而符合本标准的实现必须能够接收issuer names中包含使用如下属性值的证书。标准的属性类型已经定义在X.500系列的X.520中,实现该标准必须能够接收包含如下属性类型的issuer和subject names:

    * country,
    * organization,
    * organizational unit,
    * distinguished name qualifier,
    * state or province name,
    * common name (e.g., "Susan Housley"), and
    * serial number

    此外实现该标准时应该能够接收包含如下属性类型的issuer names和subject names:

    * locality,
    * title,
    * surname,
    * given name,
    * initials,
    * pseudonym, and
    * generation qualifier (e.g., "Jr.", "3rd", or "IV").

    此外实现该标准时必须能够接收domainComponent(DC)属性[RFC4519]。DNS提供了多级的资源标签系统,而该属性提供了一种水平化排列DNS名称的机制。它并没有替代alternative name扩展字段的DNS,实现中也没有要求需要将这些名称转化为DNS名称。语法和该属性相关的OID定义在 Appendix.A.

    X509v3 Subject Alternative Name:
        DNS:*.cnblogs.com, DNS:cnblogs.com

    证书必须能够处理Issuer DN以及subject DN(4.1.2.6)来为证书路径校验(Section 6)提供Name chaining。Name chaining通过证书中的issuer DN和CA中的subject name来进行证书路径匹配。Section 7.1描述了DN匹配模式。如果Issuer和subject名称的匹配模式和Section 7.1中描述一致,则该证书是自签的(self-issed)。Name chaining 机制可以参见数字证书基础-X.509协议 8.2章节

     4.1.2.5. Validity

    CA会维护其授权的证书的有效周期。该字段包含2个SEQUENCE的时间数据,一个为起始时间(notBefore),一个为结束时间(notAfter)。两个时间均使用UTCTime或GeneralizedTime编码。

    Validity
        Not Before: Mar 16 00:00:00 2019 GMT
        Not After : Mar 15 12:00:00 2020 GMT

    使用本标准的CA必须遵循:在2049年之前的证书使用UTCTime编码,2050年之后(含2050)使用GeneralizedTime编码。

    某些场景下的设备无法给出证书的合适超期时间,如设备可能会在其颁发的证书的public key中绑定型号和序列号信息,这类证书的有效时间应该等同于该设备的生命周期。当无法确定一个证书的超期时间时,可以给notAfer设置GeneralizedTime类型的值99991231235959Z。当证书issuer在notAfter日期之后不再维护证书状态时,issuer必须确保与该证书相关的路径证书无效,可以终止或吊销所有CA证书中用于校验该证书签名的public key并停止继续使用该public key作为信任锚(trust anchor) 。

    4.1.2.5.1. UTCTime

    世界统一时间,UTCTime,为表示日期和时间的标准ASN.1类型。UTCTime使用2个小写的数字以及精度到1分钟或1秒的时间来表示。本标准中,UTCTime包含了格林尼治平均时间且必须包含秒(即时间表示为YYMMDDHHMMSSZ),即使秒的数值为0,年字段解析如下:

    • 如果YY>=50,则解析为19YY;
    • 如果YY<50,则解析为20YY

    4.1.2.5.2. GeneralizedTime

    通用时间类型,GeneralizedTime,为使用多种精度表示时间的标准ASN.1类型。本标准中,GeneralizedTime包含了格林尼治平均时间且必须包含秒(即时间表示为YYMMDDHHMMSSZ),即使秒的数值为0。

    4.1.2.6. Subject

    subject字段表示与存储在subject的public key字段的public key相关的实体。subject可能存在于subject字段和/或 subjectAltName扩展字段中。如果subject为一个CA(即X509v3 Basic Constraints值为TRUE),则subject字段必须为一个与该CA颁发的证书的issuer字段相匹配的非空DN。如果subject为一个CRL issuer(即key usage扩展中cRLSign为TRUE),则subject字段必须为一个与该CRL颁发的CRLs的issuer字段相匹配的非空DN。如果subject的信息仅存在于subjectAltName扩展中(仅于Email地址或URI相关),则subject name必须为非空结构且subjectAltName扩展必须为critical。

    Subject: CN=*.cnblogs.com
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
            Public-Key: (2048 bit)
            Modulus:
                00:c6:b5:19:98:04:4f:37:61:32:dd:39:49:e4:30:
                c3:c6:8c:0a:e6:42:46:ce:a3:df:b5:b5:74:ac:4f:
                5c:c2:66:51:13:f6:a5:b5:d9:74:82:8b:77:7b:9a:
                82:e8:9a:45:11:c6:6a:3c:f9:8b:50:60:3f:80:ad:
                10:f8:44:15:c6:5b:65:b5:4f:8e:4a:34:02:59:9f:
                9b:40:07:46:a7:f0:02:19:8d:72:d6:13:84:54:fa:
                e4:08:aa:a8:6e:fc:8a:5c:a5:23:64:98:96:67:54:
                a9:aa:00:11:9a:44:49:4e:cc:de:91:57:e9:cd:d7:
                67:42:3c:e2:0d:77:a3:f5:30:3e:7f:ef:e5:84:fe:
                76:c5:00:67:da:98:94:e6:df:11:f6:a5:4d:26:dd:
                e8:2c:49:3b:d8:af:4d:45:e4:b5:4f:0e:f6:b3:12:
                d3:bf:39:64:15:ed:22:8b:f8:5e:1c:dd:bc:58:ce:
                75:18:35:2a:4f:06:56:d6:b3:3f:2f:b9:88:de:11:
                34:09:d2:86:cc:6f:c0:88:fd:31:1b:13:9f:be:9a:
                0f:23:ad:83:f7:df:0d:cb:b0:49:c5:84:c4:c8:73:
                6e:7c:0b:f8:93:51:7c:96:ce:97:a0:84:5a:a3:24:
                6d:82:d0:22:d3:f3:7f:30:75:d1:7e:f5:ec:29:78:
                05:6f
            Exponent: 65537 (0x10001)

    当subject非空时,该字段必须包含一个X.500 DN,且CA认证的每个subject实体的DN都是唯一的。一个CA可能为相同的subject实体颁发带相同DN的多个证书。

    subject字段为X.501类型的Name,该字段的实现要求与issuer字段相同。实现本标准可能会使用到Section7.1中的对比规则来处理无法识别的属性类型(对应的属性值使用了DirectoryString中的某个编码方式)。当无法识别的属性类型对应的属性值使用了非DirectoryString的编码方式时,可能会用到二进制比对。

    当属性值使用DirectoryString时,CA必须使用PrintableString或UTF8String,以下除外:

    • 当证书的subject表示一个CA,该字段必须使用与subject CA颁发的证书中的issuer字段相同的编码方式。因此如果subject CA颁发的证书的issuer字段的属性值使用TeletexString, BMPString或UniversalString编码,则颁发该subject CA的证书也必须使用相同的编码方式。
    • 当证书的subject表示一个CRL,该字段必须使用与subject CRL颁发的CRLs中的issuer字段相同的编码方式
    • TeletexString, BMPString或UniversalString用于向后兼容时,不应该用于新的subject。然而,当一个新的证书颁发给一个已有的subject或一个已有的证书颁发给一个新的subject时,这种情况下存在已经建立的证书可能会使用这些编码类型。证书用户应该能够接收使用这类编码类型的证书

    历史实现中有一个特例,电子邮件地址在subject的DN为emailAddress,该属性值类型为IA5String,它允许使用字符'@',但该字符并不属于PrintableString字符集,emailAddress不缺分大小写。

    相应的实现中生成带电子邮件地址的证书时,必须使用subject alternative name扩展中的rfc822Name字段。同时废弃了在subject的DN中包含emailAddress来支持历史实现,当该操作是允许的。

    4.1.2.7. Subject Public Key Info

    该字段包含了public key以及key使用的算法。该算法使用了与Section 4.1.1.2中的AlgorithmIdentifier结构。具体可以参见[RFC3279], [RFC4055]以及[RFC4491].

     4.1.2.8. Unique Identifiers

    这些字段可能仅出现在版本2或者3中(Section 4.1.2.1)。证书中的subject和issue的唯一标识符用于处理subject或issuer names重用的场景。建议不要在没有使用唯一标识符的不同实体间重用names。符合本标准的CA必须不能生成带唯一标识符的证书,但符合本标准的程序应该能够解析带有唯一标识符的证书。

    4.1.2.9. Extensions

    仅在版本为3的时候出现。若出现,该字段为SEQUENCE类型的一个或多个证书扩展。

    4.2. Certificate Extensions

    X.509 v3证书定义的扩展为用户或公钥以及在CA间的管理提供了额外的功能。X.509 v3证书的格式允许组织使用私有的扩展。证书中的扩展被定义为critical或non-critical。一个使用证书的系统在接收到设置为critical但无法识别或无法处理的证书时,必须拒绝处理该证书。一个non-critical的证书在无法识别时可能会被忽略。下面章节给出了建议使用的扩展。

    每个扩展包含一个OID以及一个ASN.1结构。当证书中出现扩展时,OID出现在extnID位置,对应的ASN.1 DER编码的结构则为8字节的字符串extnValue。一个证书不能包含相同扩展的多个实例。一个扩展包含一个布尔类型的属性critical,默认为FALSE。符合本标准的CA必须支持key identifiers (Sections 4.2.1.1 and 4.2.1.2), basic constraints (Section 4.2.1.9), key usage (Section 4.2.1.3)以及certificate policies (Section 4.2.1.4) 扩展。如果CA颁发的证书的subject字段为空,则CA必须支持subject alternative name扩展(Section 4.2.1.6)。其他的扩展则为可选择的,但将可选的扩展设置为critical可能会影响互通性。

    Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
    
    Extension  ::=  SEQUENCE  {
         extnID      OBJECT IDENTIFIER,
         critical    BOOLEAN DEFAULT FALSE,
         extnValue   OCTET STRING
                     -- contains the DER encoding of an ASN.1 value
                     -- corresponding to the extension type identified
                     -- by extnID
         }

    符合本标准的应用最小应该支持以下扩展:key usage (Section 4.2.1.3), certificate policies (Section 4.2.1.4), subject alternative name (Section 4.2.1.6), basic constraints (Section 4.2.1.9), name constraints (Section 4.2.1.10), policy constraints (Section 4.2.1.11), extended key usage (Section 4.2.1.12)以及inhibit anyPolicy (Section 4.2.1.14)。此外还应该能识别authority和subject key identifier (Sections 4.2.1.1 and 4.2.1.2) 和policy mappings (Section 4.2.1.5) 扩展。

    4.2.1. Standard Extensions

    本章节给出了X.509定义的标准证书扩展。每个扩展与一个OID相关(扩展都包含一个OID以及ASN.1结构),这些OIDs为id-ce arc的成员,id-ce定义如下:

    id-ce   OBJECT IDENTIFIER ::=  { joint-iso-ccitt(2) ds(5) 29 }

    4.2.1.1. Authority Key Identifier

    authority key identifier扩展提供了用于签名证书的私钥对应的public key的标识,在证书颁发者有多个签名key(拥有多个同时使用的key pairs)的时候会使用该扩展。可以通过key identifier(颁发者证书的subject key identifier)或issue名称和serial number来对public key进行鉴定。key identifier的作用与issue和subject字段类似,证书颁发者的Subject Key Identifier和它颁发的证书的Authority Key Identifier现同,自签证书的两个key identifier相同的。

    X509v3 Authority Key Identifier:
        keyid:55:74:4F:B2:72:4F:F5:60:BA:50:D1:D7:E6:51:5C:9A:01:87:1A:D7

    CA生成的所有证书的authorityKeyIdentifier扩必须包含authorityKeyIdentifier字段,用于简化构建证书路径,但有一个例外,当CA作为自签证书分发public key时,该字段可能会被忽略。自签证书使用与该证书的public key对应的private key进行签名(即证书颁发者同时处理公钥和私钥)。这种情况下subject 和authority的key identifier相同,但在证书路径构建过程中只用到了subject key identifier。

    由公钥衍生来的keyIdentifier字段值用于验证证书签名或生成唯一数值的方法。Section 4.2.1.2中给出了2种使用public key生成key identifiers的方法。当没有生成的key identifiers时,推荐使用这些方法或使用类似的方法(使用不同的hash算法)来生成keyidentifiers;如果已经生成了key identifier,则CA应该使用该值。

    该扩展必须被标记为non-critical

    id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 35 }
    AuthorityKeyIdentifier ::= SEQUENCE {
       keyIdentifier             [0] KeyIdentifier           OPTIONAL,
       authorityCertIssuer       [1] GeneralNames            OPTIONAL,
       authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
    
    KeyIdentifier ::= OCTET STRING

    4.2.1.2. Subject Key Identifier

     该扩展用于标识证书包含一个特定的public key。

    X509v3 Subject Key Identifier:
        55:74:4F:B2:72:4F:F5:60:BA:50:D1:D7:E6:51:5C:9A:01:87:1A:D7

    为了方便构建证书路径,相应的CA证书(即basic constraints extension的CA值为TRUE)都必须包含该扩展。CA证书的subject key identifier字段必须与它颁发的证书的authority key identifier扩展中的key identifier字段相同。证书路径校验过程中,应用不需要校验key identifier是否匹配。下面给出了2种使用public key生成key identifiers的方法:

      1. keyIdentifier由160-bit的SHA-1哈希算法对BIT STRING 类型的subjectPublicKey(不含tag,length以及未使用bit位)运算而来
      2. keyIdentifier由一个4比特的类型字段(值为0100)和由SHA1哈希subjectPublicKey所得结果的最后60比特的数据拼接组成

    对于证书使用者,subject key identifier扩展提供了一种校验应用所持的包含特定public key的证书的手段。特别是当使用来自多个CA的证书的时候,subject key identifier提供了一种快速确定public key的机制。为了帮助应用确定证书,该扩展应该包含在所有的证书中。

    该扩展必须设置为non-critical。

    id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::=  { id-ce 14 }
    SubjectKeyIdentifier ::= KeyIdentifier

    4.2.1.3. Key Usage

     key usage定义了证书包含的key的用途(如加密,数字签名,证书签名)。当一个key用于多种操作时,usage会对其进行限制,例如,当RSA key仅能进行签名校验而不能用于公钥证书以及CRLs,此时digitalSignature和/或nonRepudiation bit位会被置位。同样地,当RSA key仅用于key管理时,keyEncipherment bit位置位。

    当CA证书中的public key用于校验其他public key证书或CRLs时必须包含该扩展,此时CA应该将此扩展设置为critical

    X509v3 Key Usage: critical
        Digital Signature, Key Encipherment
    KeyUsage ::= BIT STRING {
         digitalSignature        (0),
         nonRepudiation          (1), -- recent editions of X.509 have
                              -- renamed this bit to contentCommitment
         keyEncipherment         (2),
         dataEncipherment        (3),
         keyAgreement            (4),
         keyCertSign             (5),
         cRLSign                 (6),
         encipherOnly            (7),
         decipherOnly            (8) }

    KeyUsage类型的bit位解释如下:

    • digitalSignature:当subject public key用于校验数字签名(而非对证书--bit 5和CRL签名--bit 6,它们用于实体认证服务,源数据认证服务以及集成服务)时置位。可以用于CA证书或终端证书
    • nonRepudiation:当subject public key用于校验数字签名(而非对证书--bit 5和CRL签名--bit 6)时置位,用于提供一种non-repudiation服务来防止实体错误地拒绝某些动作。当发生冲突时,因该有一个可靠的第三方来对签名的数据进行辨伪。注意该字段已经重命名为contentCommitment。digitalSignature和nonRepudiation都仅用于认证,而非加密
    • keyEncipherment:当subject public key用于对private或secret key进行加密时置位,即在密钥传输时使用。例如,当RSA public key用于加密一个对称加密中用于解密的key或非对称的private key时置位。
    • dataEncipherment:当subject public key用于直接加密原始的用户数据(没有使用中间对称加密)。注意该比特位使用的场景极少,几乎所有的应用都会密钥或密钥协商来创建对称密钥。
    • keyAgreement:当subject public key用于密钥协商的时候置位,如使用Diffie-Hellman key进行密钥管理时,该比特位置位。
    • keyCertSign:当subject public key用于校验公钥证书的签名时置位,当keyCertSign置位时,basic constrainte扩展的cA比特位也必须置位。
    • cRLSign:当subject public key用于校验证书吊销列表(如CRLs, delta CRLs, 或ARLs)中的签名时置位。
    • encipherOnly:未定义在keyAgreement bit未置位时的行为,当二者同时置位时,subject public key可能会仅仅用于在密钥协商过程中加密数据。
    • decipherOnly:未定义在keyAgreement bit未置位时的行为,当二者同时置位时,subject public key可能会仅仅用于在密钥协商过程中解密数据。

    当出现key usage扩展时,除非keyCertSign或cRLSign比特位置位,否则subject public key不能用于证书或CRLs的签名校验。如果subject public key仅用于校验证书签名和/或CRLs时,则digitalSignature和nonRepudiation不应该置位。然而当subject public key用于校验证书或CRLs以及其他对象的签名时,除keyCertSign和/或cRLSign置位之外,digitalSignature和/或nonRepudiation也可能被置位。

    当证书的keyUsage的nonRepudiation结合其他bit位使用时,根据证书使用的上下文场景,可能会出现安全隐患。特定的证书策略中给出了对digitalSignature和nonRepudiation更进一步的区分。

    本标准没有限制keyusage扩展中比特位的组合使用,但在[RFC3279], [RFC4055]和[RFC4491]中给出了针对特定算法的keyusage扩展。当证书中出现keyusage扩展时,必须至少有一个比特位置位。

    4.2.1.4. Certificate Policies

    可以首先参见Certificate Policies extension – all you should know (part 1)

    certificate policies扩展包含一个或多个策略信息,每个策略包含一个identifier (OID)以及一个可选的qualifiers(限定符)。qualifiers不会改变策略的定义。一个certificate policies扩展中不能出现多个现同的证书策略。OID即为一串特殊数字。

    X509v3 Certificate Policies:
        Policy: 2.16.840.1.114412.1.2
          CPS: https://www.digicert.com/CPS
        Policy: 2.23.140.1.2.1
    id-ce-certificatePolicies OBJECT IDENTIFIER ::=  { id-ce 32 }
    
    anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 }
    
    certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
    
    PolicyInformation ::= SEQUENCE {
         policyIdentifier   CertPolicyId,
         policyQualifiers   SEQUENCE SIZE (1..MAX) OF
                                 PolicyQualifierInfo OPTIONAL }
    
    CertPolicyId ::= OBJECT IDENTIFIER
    
    PolicyQualifierInfo ::= SEQUENCE {
         policyQualifierId  PolicyQualifierId,
         qualifier          ANY DEFINED BY policyQualifierId }
    
    -- policyQualifierIds for Internet policy qualifiers
    
    id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
    id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
    id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
    
    PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
    
    Qualifier ::= CHOICE {
         cPSuri           CPSuri,
         userNotice       UserNotice }
    
    CPSuri ::= IA5String
    
    UserNotice ::= SEQUENCE {
         noticeRef        NoticeReference OPTIONAL,
         explicitText     DisplayText OPTIONAL }
    
    NoticeReference ::= SEQUENCE {
         organization     DisplayText,
         noticeNumbers    SEQUENCE OF INTEGER }
    
    DisplayText ::= CHOICE {
         ia5String        IA5String      (SIZE (1..200)),
         visibleString    VisibleString  (SIZE (1..200)),
         bmpString        BMPString      (SIZE (1..200)),
         utf8String       UTF8String     (SIZE (1..200)) }

    在终端证书中(end entity certificate),该策略信息给出了谁颁发了该证书以及颁发该证书的目的。CA证书中的策略信息限制了包含该证书的证书路径中使用的策略集。如果一个CA不想限制(包含该证书的)证书路径使用的策略集合,则将特殊的策略--anyPolicy设置为{ 2 5 29 32 0 }。下图为博客园的证书策略,可以看到该证书的目的描述,在右下角的"颁发者说明中",可以直接连接到CPS Pointer指向的链接:https://www.digicert.com/CPS。windows推荐使用的qualifier为CPS Pointer(user notice限制了字符串最大长度为200字节)。

    当应用对策略有特殊的要求,则它会将可接受的策略列表与证书策略的OIDs进行比较。如果扩展为critical,则应用必须能够解析该扩展,否则拒绝该证书。

    为了提高可交互性,本标准建议每条策略信息仅包含一个OID。当一个OID不满足需求时,强烈建议使用本章节确定的qualifiers。当qualifiers配合anyPolicy使用时,则必须使用本章节确定的qualifiers。仅考虑路径校验返回的qualifier。可以参考Certificate Policies extension – all you should know (part 1)中对policies有效性的说明。

    本标准定义了给证书策略作者和证书颁发者使用的两种qualifiers,即CPS Pointer和User Notice qualifiers。CPS Pointer qualifier包含指向CPS(Certification  Practice Statemen)的指针,指针格式为URI。使用本地方式处理该qualifier的需求。

    user notice用于向依赖该证书的一方显示相关信息,且仅(向用户)显示路径校验返回的qualifier。当notice重复时,仅显示其中一个副本。为了防止重复,该qualifier应该仅存在于终端证书以及用于颁发证书到其他组织的CA证书中。user notice有2个可选字段:noticeRef和explicitText字段。相应的CA不应该使用noticeRef选项。

    NoticeReference ::= SEQUENCE {
         organization     DisplayText,
         noticeNumbers    SEQUENCE OF INTEGER }
    • noticeRef,用于命名组织以及使用数字标识该组织的文本声明。例如,使用noticeRef标识一个组织"CertsRUs“,notice number为1。典型实现中,应用软件会使用通告文件来保存CertsRUs当前的通告信息,应用会从该文件中收取并显示这些通告文本。消息可能会允许软件根据允许环境选择特定的语言。
    • explicitText字段包含了证书中的文本声明。explicitText字段为最大200字节的字符串。CA可能会使用UTFString编码该字段,也可能使用IA5String。CA不能使用VisibleString或BMPString编码该字段。explicitText字符串不能包含任何控制字符(即,U+0000 ~ U+001F 和 U+007F ~ U+009F)。当使用UTF8String编码时,所有的字符都应该遵循unicode标准。

    当noticeRef和explicitText选项同时出现在qualifier中且应用软件能够使用noticeRef选项定位通告文本时,则应该显示该文本,否则不应该显示explicitText字符串。

    注:由于explicitText最大程度为200字符,有些非标CA会超过该限制。因此证书应该能够妥善处理这些explicitText字段超过200字节的证书。

    4.2.1.5. Policy Mappings

    该扩展用于CA证书,列出了一对或多对OIDs,每对包含一个issuerDomainPolicy和一个subjectDomainPolicy,用于表明issuing CA的issuerDomainPolicy等同于subject CA的issuerDomainPolicy。主要用于交叉验证(cross-certify)

    issuing CA的用户可能会接收特定应用的issuerDomainPolicy。policy mapping定义了与(根据issuerDomainPolicy可接收的)subject CA相关的策略。policy mappings中的issuerDomainPolicy应该会出现在相同证书的policies扩展中。

    通常情况下,证书的policy mappings扩展的issuerDomainPolicy字段中的策略不能够作为证书路径中后续证书可接受的策略。一些场景下,CA期望将一个策略p1映射到另一个策略p2,但仍然希望p1中的issuerDomainPolicy能够接受并包含在后续证书中,这种情况是可能发生的,如当CA从使用p1策略转换为使用p2策略时,它的p1策略下还存在有效的证书,此时CA可以在其证书中包含这两种policy mappings,每个policy mapping的issuerDomainPolicy都应该包含p1;一个policy mapping包含带有p1的issuerDomainPolicy,另一个则包含带有p2的issuerDomainPolicy。

    CA或应用都可能支持该扩展,且CA应该将该扩展标记为critical。

    id-ce-policyMappings OBJECT IDENTIFIER ::=  { id-ce 33 }
    PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
         issuerDomainPolicy      CertPolicyId,
         subjectDomainPolicy     CertPolicyId }

    4.2.1.6. Subject Alternative Name

    subject alternative name允许将特征信息绑定到证书的subject(即subject字段表示的对象)。该特征包含可以替代证书的subject字段,或为subject字段提供额外的身份认证。可选的内容包括电子邮件地址,DNS名称,IP地址,以及URI,以及本地自定义内容。可能会使用到多种名称格式,每种名称格式对应多个实例。当该特征需要绑定到证书时,必须使用subject alternative name (或issuer alternative name)扩展。DNS名称可能同时出现在subject字段的domainComponent属性中。注意subject字段中出现的名称并不要求转换为DNS格式的名称。实现中没有要求将subject字段中的名称转变为DNS名称

    X509v3 Subject Alternative Name:
        DNS:*.cnblogs.com, DNS:cnblogs.com

    由于subject alternative name明确绑定到public key,因此subject alternative name中的所有内容必须通过CA验证。

    id-ce-subjectAltName OBJECT IDENTIFIER ::=  { id-ce 17 }
    
    SubjectAltName ::= GeneralNames
    GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
    GeneralName ::= CHOICE {
         otherName                       [0]     OtherName,
         rfc822Name                      [1]     IA5String,
         dNSName                         [2]     IA5String,
         x400Address                     [3]     ORAddress,
         directoryName                   [4]     Name,
         ediPartyName                    [5]     EDIPartyName,
         uniformResourceIdentifier       [6]     IA5String,
         iPAddress                       [7]     OCTET STRING,
         registeredID                    [8]     OBJECT IDENTIFIER }
    
    OtherName ::= SEQUENCE {
         type-id    OBJECT IDENTIFIER,
         value      [0] EXPLICIT ANY DEFINED BY type-id }
    
    EDIPartyName ::= SEQUENCE {
         nameAssigner            [0]     DirectoryString OPTIONAL,
         partyName               [1]     DirectoryString }

    更进一步说,如果证书的subject特征中只有一种alternative name格式(如电子邮件地址),则DN必须为空,同时必须存在subjectAltName扩展。如果subject字段包含空的结构,则issuing CA必须包含subjectAltName扩展且标记为critical。当证书中的subjectAltName包含非空的subject DN,CA应该将subjectAltName扩展标记为非critical。

    当subjectAltName扩展包含电子邮件地址,则该地址必须保存为rfc822Name格式,rfc822Name为Section 4.1.2 of [RFC2821]中定义的"邮箱"。邮箱的格式为"Local-part@Domain"。注意邮箱前面没有词组,后面没有注释,不支持"<"和">"。国际化的电子邮件地址定义在Section 7.5。

    当subjectAltName扩展包含IP地址时,地址必须使用网络序存储的8字节字符串。

    当subjectAltName扩展包含DNS时,域名必须使用dNSName格式(IA5String)。名称格式必须为"preferred name syntax"(定义于Section 3.5 of [RFC1034],修改于Section 2.1 of   [RFC1123])。虽然域名中允许大小写,但功能上并不区分大小写。此外,由于” “是一个合法的域名,subjectAltName扩展中不能使用”  “作为域名。最后不能使用DNS表达式来表示电子邮件地址(如使用subscriber.example.com替换subscriber@example.com)。国际化的域名定义在Section 7.2。

    当subjectAltName扩展包含URI时,URI必须使用uniformResourceIdentifier格式(IA5String),且不能为相对URI[RFC3986]。名称必须同时包含一个scheme(http或ftp)以及一个scheme-specific-part(如下)。包含认证([RFC3986], Section 3.2)的URI必须包含一个与host相同的域名或IP地址。国际化的资源标识符定义在Section 7.4

    absolute-URI  = scheme ":" hier-part [ "?" query ]

    如[RFC3986]定义,scheme名称是不区分大小写的(如"http"等同于"HTTP")。主机信息同样不区分大小写,但其他的scheme- specific-part可能会区分大小写。对比URI的规则参见Section 7.4

    当subjectAltName的directoryName字段包含一个DN时,则使用issuer字段中使用的相同DN的编码规则 。一个CA认证的每个subject实例的(issuer字段中的)DN必须是唯一的。CA可能对一个subject实体颁发多个使用相同的DN的证书。即1个CA--->1或多个证书(相同DN)---->一个subject实体

    subjectAltName可能在otherName字段中包含额外的名称类型。格式和语法使用type-id字段表示,名称使用otherName中的value字段表示。

    Subject alternative names可能会使用与subject DN相同的name constraints扩展来对名称进行限制

    如果出现了subjectAltName扩展,则sequence结构中必须包含至少一个表项。与subject字段不同,CA不能颁发subjectAltNames中含空GeneralName字段的证书。由于空字符串是有效的IA5String,因此不允许出现这种字符串,本标准没有定义如何处理这类证书。

    最后,本标准没有定义Subject alternative names如何使用通配符,当应用有这样的需求时,应该定义这种语法。

    4.2.1.7. Issuer Alternative Name

    与4.2.1.6类似,Issuer Alternative Name扩展与证书issuer的身份特征关联。编码方式与SAN相同。Issuer alternative names不作为路径校验算法(Section 6)的一部分,即Issuer alternative names没有用于name chaining且没有使用name constraints扩展进行名称限制。CA应该将该扩展标记为非critical

    id-ce-issuerAltName OBJECT IDENTIFIER ::=  { id-ce 18 }
    IssuerAltName ::= GeneralNames

     4.2.1.8. Subject Directory Attributes

    Subject Directory Attributes用来携带subject的身份属性(如国籍)。该扩展可以携带一个或多个属性,CA必须将该扩展标记为非critical。

    id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::=  { id-ce 9 }
    SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute

    4.2.1.9. Basic Constraints

    basic constraints定义了subject是否是一个CA,以及包含该证书的有效证书路径的最大深度。cA字段表示public key是否可以用于校验证书签名。如果cA没有置位,则Key Usage扩展中不能使用keyCertSign比特位(该比特位表示public key用于校验证书)。如果版本3的证书中没有出现该扩展,或者出现该扩展但cA没有置位,则public key不能用于校验签名。

    pathLenConstraint字段仅在cA置位且Key Usage扩展的keyCertSign置位的时候生效。这种情况下,它给出了有效证书路径中可能跟在该证书后面的最大非自行颁发的中间证书数量(注意,证书路径的最后一个证书不是中间证书,不受此数量限制。通常最后一个证书称为终端证书,但它可能是一个CA证书)。pathLenConstraint为0表示后续有效证书路径中没有非自发(Self-issued)的中间CA证书。当该字段出现时,其必须大于或等于0;反之没有数量限制。

    当CA证书中的public key用于校验证书的数字签名时,必须在所有CA证书中包含该扩展,且必须将此扩展标记为critical。当CA的public key不用于校验证书的数字签名时,可以将该扩展标记为critical或非critical,这类证书包括将public key用于校验CRLs的数字签名CA证书,以及包括含带与证书注册协议配合使用的key management public keys的CA证书。在终端证书中,该扩展可以被标记为critical或非critical。

    只有在cA置位且key usage扩展的keyCertSign置位后,CA才能包含pathLenConstraint字段。

    X509v3 Basic Constraints:
        CA:TRUE,pathlen:0
    id-ce-basicConstraints OBJECT IDENTIFIER ::=  { id-ce 19 }
    BasicConstraints ::= SEQUENCE {
         cA                      BOOLEAN DEFAULT FALSE,
         pathLenConstraint       INTEGER (0..MAX) OPTIONAL }

    4.2.1.10. Name Constraints

    可以参考X.509 Name Constraints certificate extension – all you should know,该扩展不常使用,仅用于某些特定的PKI部署场景。它允许CA证书包含授权为其颁发证书的域名模式的白名单和黑名单,最常用的为如下几类:

    • Directory Name (X.500 distinguished name)
    • DNS Name
    • IP Address (IPv4 and IPv6)
    • RFC 822 name (email)
    • User Principal Name (UPN)

    name constraints仅能用于CA证书中,表示一个名称空间,它包含了路径证书中所有下属证书的subject names。可以用于限制subject的DN以及SAN,只有出现特定格式的名称时,该限定才会生效,如果证书中没有该格式的名称,则该证书是可以接收的。

    name constraints不适用于自发(Self-issued)证书(除非该证书是路径的最后一个证书)。可以防止使用name constraints的CA使用自发(self-issued)证书实现key翻转。

    使用permitted和excluded name subtree来定义限定的内容(restrictions)。任何与excludedSubtrees字段匹配的名称是无效的(即便该名称存在于permittedSubtrees中)。CA必须将该扩展标记为critical且不应该限定name constraints的格式为x400Address, ediPartyName, 或registeredID。CA不能颁发name constraints为空的证书,即必须出现permittedSubtrees或excludedSubtrees。

    id-ce-nameConstraints OBJECT IDENTIFIER ::=  { id-ce 30 }
    
         NameConstraints ::= SEQUENCE {
              permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
              excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
    
         GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
    
         GeneralSubtree ::= SEQUENCE {
              base                    GeneralName,
              minimum         [0]     BaseDistance DEFAULT 0,
              maximum         [1]     BaseDistance OPTIONAL }
    
         BaseDistance ::= INTEGER (0..MAX)

    符合本标准的应用必须能够处理directoryName name格式的name constraints,且能够处理使用rfc822Name, uniformResourceIdentifier, dNSName, 和iPAddress格式的name constraints。如果name constraints扩展被标记为critical,且将constraints限制为某个特定的格式,如果(证书路径中)从属证书的subject字段或subjectAlt Name扩展中出现了该格式的实例,则证书必须处理该constraints或拒绝该证书。

    本标准中minimum和maximum字段没有使用任何name格式,minimum必须为0,必须不能出现maximum。然而当应用程序在后续证书的(critical的)name constraints中的minimum和maximum使用了特定格式的其他值,此时应用必须能够处理这些字段或拒绝该证书。

    对于URI,constraint作用于名称的主机部分。constraint必须是一个完全合格的域名,可能是一个主机或域。如"host.example.com"或"*.example.com"。当一个constraint以句点开始时,可能扩展为一个或多个标签,即".example.com"满足host.example.com和my.host.example.com。然而".example.com"不满足“example.com”。当constraint不以句点开始时,它满足一个主机。如果一个constraint为URI名称格式,且从属证书包含带URI的subjectAltName扩展,但扩展中的URI不包含带(作为完全合格的域名格式的)主机名的权威组件时(即URI要么不包含权威组件,要么包含的权威组件的主机名为IP地址),则应用必须拒绝该证书。

    用于电子邮件地址的name constraint可能会指定一个特定的邮箱,一个主机的所有地址或一个域中的所有邮箱。为了包含一个特定的邮箱,constraint为一个完整的邮箱地址,例如”root@example.com“主机"example.com"上的root邮箱。为了指定一个特定主机的所有邮箱地址,constraint指定为主机名称,例如constraint ”example.com“满足在主机”example.com”上的任何邮箱。为了指定一个域的所有地址,constraint使用以句点开始的URI,如".example.com"表示"example.com"域中的所有邮箱地址,但不包含主机"example.com"的邮箱地址。

    DNS的name constraint表示为host.example.com。任何DNS名称可以简单地在名称左侧添加标签来满足name constraint。如www.host.example.com满足constraint,但host.example.com不满足。

    传统实现中存在电子邮件地址嵌入在subject DN为emailAddress的属性中(Section 4.1.2.6),当constraint限制为rfc822Name格式,但证书不包含SAN时,则subject DN的emailAddress属性必须使用rfc822Name格式的constraint。

    directoryName格式的限定必须作用于证书的subject字段(当证书包含非空subject字段时)和subjectAltName扩展的所有directoryName类型的名称上。

    但对directoryName的格式进行限定时,必须对比DN属性。实现中必须执行Section7.1中描述的DN对比。当CA颁发具有格式限制的证书时,directoryName不应该依赖ISO DN名称比较算法,这意味着名称限制必须使用与subject字段或subjectAltName扩展相同的编码

    iPAddress(Section 4.2.1.6)的语法必须使用下面内容作为name constraints。对于IPV4地址,iPAddress字段必须包含8个字节,使用RFC 4632编码方式表示一个网段。对于IPV6地址,iPAddress字段必须包含32字节。例如C类地址192.0.2.0表示为C0 00 02 00 FF FF FF 00,CIDR为192.0.2.0/24

    其他处理name constraints中的规则和编码参见Section 7.

    本标准没有定义otherName, ediPartyName, 和 registeredID的name constraint。然而其他文档中可能描述了其他name type的name constraints。

    4.2.1.11. Policy Constraints

    policy constraints扩展可以用于颁发CA的证书中,它有两种方式来约束路径校验,即通过禁止policy mapping或要求路径中的每个证书都包含一个可接受的策略识别码(OID)。

    如果出现inhibitPolicyMapping字段,该字段的值表示在路径中禁止进行policy mapping前(指路径以本证书开始的某个节点前)的证书的数目。例如,证书中该字段值为1表示该证书(的subject)颁发的证书中的policy mapping可以被处理,但路径中的其他证书则不能。

    如果出现requireExplicitPolicy字段,该字段的值表示在路径中要求一个明确的policy前(指路径以本证书开始的某个节点前)的证书的数目。当要求一个明确的policy时,则要求该路径中的所有证书的policies扩展包含该一个可接受的policy identifier。一个可接受的policy identifier指证书路径中的用户要求的policy的identifier或通过policy mapping声明的policy identifier。

    id-ce-policyConstraints OBJECT IDENTIFIER ::=  { id-ce 36 }
    
    PolicyConstraints ::= SEQUENCE {
         requireExplicitPolicy           [0] SkipCerts OPTIONAL,
         inhibitPolicyMapping            [1] SkipCerts OPTIONAL }
    
    SkipCerts ::= INTEGER (0..MAX)

    应用必须能够处理requireExplicitPolicy字段,并且应该能够处理inhibitPolicyMapping字段。支持inhibitPolicyMapping字段的应用也必须同时支持policymapping扩展。如果policyConstraint扩展标记为critical且出现inhibitPolicyMapping字段,则不支持inhibitPolicyMapping字段的应用必须拒绝该证书。

    CA不能颁发policy constraint为空的证书,即inhibitPolicyMapping和requireExplicitPolicy字段必须至少有一个非空。本标准没有定义客户端如何处理带空policy constraint字段的证书。

    CA必须将该扩展标记为critical。

     4.2.1.12. Extended Key Usage

    该扩展表示被认证的public key的(一个或多个)purposes(用途),可以替换或作为key usage扩展的补充。该扩展通常出现在终端证书(end entity certificates)中,定义如下。key purposes可能由有需求的任何组织定义,用于验证key purposes的object identifiers必须由IANA 或ITU-T Recommendation X.660分配。

    id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }
    ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
    KeyPurposeId ::= OBJECT IDENTIFIER
    X509v3 Extended Key Usage:
        TLS Web Server Authentication, TLS Web Client Authentication

    该扩展可能依据证书颁发者的选择设置为critical或非critical。

    如果出现该扩展,则该证书只能用于扩展中指明的某一个purpose。如果使用多个purpose指出应用需求,但无法识别所有的purposes,则只要出现所需要的那个purpose即可。使用证书的应用可能会要求出现key usage扩展并同时指明该证书的purpose,并以此判断证书是否可以被该接受。

    如果一个CA的extended key usage可以满足应用需求,但不希望限制(key usage扩展中的)key的使用,则CA可以包含除了应用要求的key purposes之外的特殊字段KeyPurposeId anyExtendedKeyUsage。当出现anyExtendedKeyUsage的KeyPurposeId时,CA不应该将该扩展标记为critical。如果一个应用要求某个purpose,但证书中仅包含anyExtendedKeyUsage而不包含应用需要的OID,则应该可能会拒绝该证书。

    如果证书同时包含key usage和extended key usage扩展,则必须单独处理者两个扩展,且证书的(某个)purpose必须与两个同时扩展保持一致。如果无法同时与两个扩展保持一致,则该证书不能用于任何purpose。

    key usage purposes定义如下:

    anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
    
    id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
    
    id-kp-serverAuth             OBJECT IDENTIFIER ::= { id-kp 1 }
    -- TLS WWW server authentication
    -- Key usage bits that may be consistent: digitalSignature,
    -- keyEncipherment or keyAgreement
    
    id-kp-clientAuth             OBJECT IDENTIFIER ::= { id-kp 2 }
    -- TLS WWW client authentication
    -- Key usage bits that may be consistent: digitalSignature
    -- and/or keyAgreement
    
    id-kp-codeSigning             OBJECT IDENTIFIER ::= { id-kp 3 }
    -- Signing of downloadable executable code
    -- Key usage bits that may be consistent: digitalSignature
    
    id-kp-emailProtection         OBJECT IDENTIFIER ::= { id-kp 4 }
    -- Email protection
    -- Key usage bits that may be consistent: digitalSignature,
    -- nonRepudiation, and/or (keyEncipherment or keyAgreement)
    
    id-kp-timeStamping            OBJECT IDENTIFIER ::= { id-kp 8 }
    -- Binding the hash of an object to a time
    -- Key usage bits that may be consistent: digitalSignature
    -- and/or nonRepudiation
    
    id-kp-OCSPSigning            OBJECT IDENTIFIER ::= { id-kp 9 }
    -- Signing OCSP responses
    -- Key usage bits that may be consistent: digitalSignature
    -- and/or nonRepudiation

     4.2.1.13. CRL Distribution Points

    CRL distribution points扩展用于指明如何获取CRL信息。该扩展应该标记为非critical,但建议CA和应用支持该扩展。

    X509v3 CRL Distribution Points:
    
        Full Name:
          URI:http://crl3.digicert.com/DigiCertGlobalRootCA.crl

    cRLDistributionPoints扩展由DistributionPoint结构构成。一个DistributionPoint包含3个字段:distributionPoint, reasons, 和cRLIssuer,每个字段都是可选的,但DistributionPoint不能仅由reason字段构成,distributionPoint和cRLIssuer必须出现一个。如果证书颁发者不是CRL颁发者,则cRLIssuer字段必须出现且包含CRL颁发者的名称。如果证书颁发者同时也是CRL颁发者,则相应的CA必须忽略cRLIssuer字段,但必须包含distributionPoint字段。

    当distributionPoint字段包含一个directorName时,该directoryName的表项会包含当前CRL相关的reason以及与cRLIssuer相关的CRL。CRL可能存储在certificateRevocationList或authorityRevocationList属性中。本地配置了应用应该从哪类directory server获取CRL,以及使用何种协议访问directory(如DAP或LADP)。

    如果DistributionPointName包含一个通用类型的URI,则必须遵守下属语法:URI为指向当前CRL的指针,且该CRL后续会被cRLIssuer颁发。当使用HTTP或FTP URI时,URI必须指向DER编码的CRL[RFC2585]。使用URI接入HTTP服务器时,URI应该指定media类型,即在响应的首部的content-type字段中指明application/pkix-crl。当使用LADP URI[RFC4516]时,URI必须包含一个<dn>字段,该字段包含CRL的DN表项;必须包含一个<attrdesc>字段,该字段包含对CRL所持有的属性的描述[RFC4523];应该包含一个<host>字段(如, <ldap://ldap.example.com/cn=example%20CA,dc=example,dc=com? certificateRevocationList;binary>)。省略<host>导致客户端依据之前的信息查找一个合适的服务器。当该字段出现时,DistributionPointName应该至少包含一个LDAP或HTTP URI。

    如果DistributionPointName包含一个值nameRelativeToCRLIssuer,该值给出了DN段的内容,该段附加在CRL颁发者的X.500 DN之后,用于获取distribution point name。如果DistributionPoint中出现cRLIssuer字段,则该name段会附加到它所包含的DN中,否则会附加到issuer的DN中,CA不能使用nameRelativeToCRLIssuer 来指定distribution point names。当cRLIssuer 包含多个DN时,DistributionPointName不能使用nameRelativeToCRLIssuer。

    如果DistributionPointName忽略reason字段,则CRL必须包含所有reasons的撤销信息。推荐使用reason码(见下)。当CA证书包含cRLDistributionPoints 扩展时,必须包含至少一个指向(涵盖所有reasons的)CRL的DistributionPoint 

    cRLIssuer指出签名和颁发CRL的实体。如果出现该字段,cRLIssuer必须包含DistributionPoint指向的CRL的issuer字段的DN。cRLIssuer字段的编码必须与CRL的issuer字段相同。如果cRLIssuer字段包含了与CRL所在的X.500或LDAP directory表项不匹配的DN,则相应的CA必须包含distributionPoint字段。

    id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::=  { id-ce 31 }
    
    CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
    
    DistributionPoint ::= SEQUENCE {
         distributionPoint       [0]     DistributionPointName OPTIONAL,
         reasons                 [1]     ReasonFlags OPTIONAL,
         cRLIssuer               [2]     GeneralNames OPTIONAL }
    
    DistributionPointName ::= CHOICE {
         fullName                [0]     GeneralNames,
         nameRelativeToCRLIssuer [1]     RelativeDistinguishedName }
    
    ReasonFlags ::= BIT STRING {
         unused                  (0),
         keyCompromise           (1),
         cACompromise            (2),
         affiliationChanged      (3),
         superseded              (4),
         cessationOfOperation    (5),
         certificateHold         (6),
         privilegeWithdrawn      (7),
         aACompromise            (8) }

    4.2.1.14. Inhibit anyPolicy

    inhibit anyPolicy用在颁发CA的证书中。inhibit anyPolicy扩展表明特殊的anyPolicy OID(值为{ 2 5 29 32 0 }),除非其出现在中间自发证书中,否则不能显示地匹配到其他证书策略。其值表示在证书路径中不允许anyPolicy前的其他非自发证书的数目。如值1表示该证书中的subject颁发的证书中的anyPolicy可以被处理,但其他证书则不能。
    CA必须将该扩展标记为critical

    id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::=  { id-ce 54 }
    InhibitAnyPolicy ::= SkipCerts
    SkipCerts ::= INTEGER (0..MAX)

    4.2.1.15. Freshest CRL (a.k.a. Delta CRL Distribution Point)

     freshest CRL扩展用于指明如何获取delta CRL信息。该扩展必须标记为非critical。该扩展的句法与cRLDistributionPoints 相同

    id-ce-freshestCRL OBJECT IDENTIFIER ::=  { id-ce 46 }
    FreshestCRL ::= CRLDistributionPoints

    4.2.2. Private Internet Extensions

    本章节定义了PKI(Public Key Infrastructure)中使用的2种扩展。这些扩展可以用于指导应用获取issuer或subject的在线信息。每个扩展包含access methods(访问方法)和access locations(访问地址)的列表。access methods为一个Object identifiers,表示可用的消息类型。access locations为GeneralName,隐含了消息的位置和消息的格式以及获取消息的方式。

    Object identifiers用于私有扩展。与私有扩展相关的Object identifiers定义在id-pkix中的id-pe。PKI未来定义的扩展预计会定义在id-pe中。

    id-pkix  OBJECT IDENTIFIER  ::=
             { iso(1) identified-organization(3) dod(6) internet(1)
                     security(5) mechanisms(5) pkix(7) }
    
    id-pe  OBJECT IDENTIFIER  ::=  { id-pkix 1 }

     4.2.2.1. Authority Information Access

    当出现authority information access扩展时,该扩展用于指出证书中的issuer如何访问信息和服务。这些消息和服务可能包括在线校验服务和CA策略数据。(CRLs的位置不在本扩展指定范围内,它由cRLDistributionPoints扩展提供)。该扩展可能包含在终端证书或CA证书中,相应的CA必须将该扩展标记为非critical

    id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 }
    
    AuthorityInfoAccessSyntax  ::=
            SEQUENCE SIZE (1..MAX) OF AccessDescription
    
    AccessDescription  ::=  SEQUENCE {
            accessMethod          OBJECT IDENTIFIER,
            accessLocation        GeneralName  }
    
    id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }
    id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 }
    id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 }
    Authority Information Access:
        OCSP - URI:http://ocsp.dcocsp.cn
        CA Issuers - URI:http://cacerts.digicert.com/EncryptionEverywhereDVTLSCA-G1.crt

    AuthorityInfoAccessSyntax中的每个表项描述了证书issuer提供的额外信息的格式和位置(上述例子给出了用于查询证书吊销状态的OCSP)。消息的类型和格式由accessMethod字段指定,accessLocation字段指定了消息的位置。消息检索机制可能由accessMethod或accessLocation提供。

    本标准的定义了2中accessMethod OIDs:id-ad-caIssuers和id-ad-ocsp.

    在public key证书中,当额外的信息中列出了用于颁发CA(该CA颁发了包含该扩展的证书)的证书时,会使用到id-ad-caIssuers OID。CA issuer description用于帮助证书用户选择终止于该证书用户(的信任节点)的路径。

    当id-ad-caIssuers作为accessMethod时,accessLocation字段描述了用于获取相关描述信息的服务端和访问协议。accessLocation,定义为GeneralName,可以有多种格式。

    当accessLocation为directoryName格式时,本地配置应用如何从directory server获取信息。当该扩展指向CA证书时,crossCertificatePair和/或cACertificate属性中的表项中的directoryName会包含该CA证书。本地配置应用访问directory (e.g., DAP or LDAP)的协议。

    当可以使用LDAP获取信息时,accessLocation应该为uniformResourceIdentifier。LDAP URI必须包含一个<dn>字段,该字段含证书包含的DN;必须包含<attributes>字段,用于列出持有DER编码的证书或交叉证书对[RFC4523]的属性的descriptions,descriptions中应该包含<host>(如 <ldap://ldap.example.com/cn=CA,dc=example,dc=com?cACertificate;binary,crossCertificatePair;binary>)。忽略<host>(如, <ldap:///cn=exampleCA,dc=example,dc=com? cACertificate;binary>)可能会导致客户端根据先前的信息选择连接一个合适的服务端。

    当可以通过HTTP or FTP获取信息时,accessLocation必须是uniformResourceIdentifier 且URI必须执向一个DER编码的证书或包含BER或DER编码的"certs-only" CMS的(证书)集合[RFC2797]

    支持HTTP或FTP访问证书的应用必须能够接收DER编码的证书且可以接收"certs-only" CMS消息。

    HTTP服务器使用URI访问时,应该在DER编码的证书的响应首部的content-type字段中指明application/pkix-crl,且应该在"certs-only" CMS响应的content-type首部字段的media-type中指明application/pkcs7-mime。对于FTP,包含一个DER编码的证书的文件应该改使用".cer"前缀,包含"certs-only" CMD消息的文件应该使用".p7c"前缀。客户端可能使用media-type或文件扩展来暗示这些内容,但不能仅仅依赖media-type或server响应中的文件扩展。

    id-ad-caIssuers accessLocation的语法格式未定义。

    authorityInfoAccess扩展可能包含id-ad-caIssuers accessMethod的多个实例。不同的实例可能指定了相同或不同消息的访问方法。当使用了id-ad-caIssuers accessMethod,应该由至少一个实例指明accessLocation为HTTP或LDAP URI。

    当可以使用Online Certificate Status Protocol (OCSP)[RFC2560]来获取证书的吊销信息时会用到id-ad-ocsp OID。

    当id-ad-ocsp为accessMethod时,accessLocation字段为OCSP响应者的位置 [RFC2560]。

     4.2.2.2. Subject Information Access

    6. Certification Path Validation

    PKI证书路径校验算法基于X.509。证书路径处理主要涉及校验subject DN(和/或SAN)和subject public key的绑定关系。(包含依赖方指定的path和inputs的)证书中指定的constraint设置了关系绑定的范围,basic constraints和policy constraints扩展允许自动化地做出证书路径的处理决定。

    本章节描述了一种校验证书路径的算法,本标准没有要求实现该算法,但必须提供与该处理相同的外部行为结果。只要能导出正确的结果,实现中可以使用任何算法。

    Section 6.1给出了基本的路径校验。有效的路径以信任锚(trust anchor)发布的证书作为起点。该算法要求使用CA的public key,CA的名称以及该key可能用到的用于校验路径集合的所有constraints。

    使用策略来选举信任锚,该策略可能为使用分级PKI中的顶级CA,颁发验证者证书的CA,或者网络上的PKI中的CA。不管使用哪种可信锚,路径校验处理的结果都是相同的。此外,不同的应用可能会依赖不同的可信锚,或可能接受以某个可信锚集合中的任何一个开始的路径。

    Section 6.2描述了特定实现中用于路径校验的方法。

    Section 6.3描述了用于在证书颁发者使用CRLs吊销机制的时候确定一个证书是否已经被吊销的必要步骤。

    6.1. Basic Path Validation

    本文规定了一个用于X.509证书的处理的算法。符合标准的实现必须包含与外部处理逻辑相同的X.509路径处理过程。然而,该算法对一些证书的扩展的支持是可选的。不支持这些扩展的客户端可能会忽略掉路径校验算法中对应的特定步骤。例如客户端没有要求要支持policy mapping扩展,则不支持该扩展的客户端可能会忽略掉该扩展处理的步骤。注意当客户端不支持一个critical的扩展时,必须忽略该证书 。Section 4和Section 5中给出了在证书和CRL的字段以及扩展中的推荐值。本章节使用的算法没有限制必须遵循本标准的证书和CRLs,因此算法仅包含用于校验证书路径是否符合X.509规定,但不包含且不推荐校验证书是否符合本规定。

    本章节的算法根据当前日期和时间对证书进行校验,相应的实现可能会支持根据过去某个时间点进行校验,注意该机制无法对超出该(有效)证书的有效期的时间点进行校验,
    信任锚(trust anchor)作为算法的输入(inputs),没有要求相同的信任锚会用于多条证书路径的校验。不同的信任锚可能用于不同路径的校验,参见Section 6.2。

    路径校验的主要目的是使用基于可信锚的public key,校验目标证书的subject DN(或SAN)与subject public key的绑定关系。大多数情况下,目标证书为终端证书,但目标证书也可能是一个CA证书,此时subject public key用于某种目的,而非对某个证书的public key的签名进行验证。验证名称和subject public key的绑定关系需要获取支持该绑定的一系列证书。如何获取这些证书不在本文范围内。

    为了满足该目标,路径校验会涉及到其他过程,预期的证书路径校验需要满足如下条件;

    1. 对于x in {1, ..., n-1},证书x的subject为证书x+1的issuer
    2. 证书1作为可信锚
    3. 证书n作为需要被校验的证书,即目标证书(target certificate)
    4. 对于所有的x in {1, ..., n},在处理期间是有效的

    证书路径中的相同证书不能出现多次。

    当信任锚为自签(self-signed)证书时,该自签证书不包含在预期的证书路径中。Section 6.1.1.描述了信任锚作为路径校验算法的输入。

    特定的证书路径可能无法满足所有应用的需求,因此一个应用可能会修改该算法来限制有效路径的集合,路径校验过程同时(基于policies扩展, policy mappings扩展, policy constraints扩展,和inhibit anyPolicy扩展)决定了该路径下有效的证书策略。为了达到该目标,路径校验算法会创建一个valid policy tree,如果路径上的证书的策略集合有效且非空,则会创建一个深度为n的valid policy tree;否则结果为一个空的valid policy tree。

    如果相同的DN出现在subject和issuer字段时,该证书为自发(self-issued)证书。通常路径中每个证书的issuer和subject是不同的,然而一个CA可能给它自身颁发一个证书,用于支持key翻转或改变证书策略。这类self-issued证书不算在路径长度计算或name constraints范围内。

    本章的算法包含4个基本步骤:(1)初始化,(2)基本证书处理,(3)准备下一个证书,(4)封装。步骤(1)和(4)仅执行一次,步骤(2)会对路径的所有证书执行,步骤(3)会对路径中除最终证书执行。基本流程如下:

    6.1.1. Inputs

    本算法假设路径处理过程使用了使用如下9个输入:

    a) 预期的证书路径长度n

    b) 当前日期/时间

    c) user-initial-policy-set:证书用户可接受的证书策略的OID集合。如果用户不关心证书策略,则user-initial-policy-set会包含特定的值any-policy

    d) 信任锚信息,描述了证书路径中作为信任锚的CA,信任锚信息包括

    • 信任的issuer 名称
    • 信任的public key算法
    • 信任的public key,以及
    • 可选择,与public key相关的public key参数

    信任锚信息可能会通过自签证书格式提供给路径校验。当信任锚信息以证书格式提供时,subject字段的名称作为信任的issuer名称,且subjectPublicKeyInfo字段中的内容作为信任的public key算法的源和信任的public key。信任锚是可信的,因为它会使用可靠的带外程序传输到路径处理过程中。如果信任的public key算法需要参数,则参数会与信任的public key一并提供。

    e) initial-policy-mapping-inhibit,表示证书路径是否允许policy mapping

    f ) initial-explicit-policy,表示是否路径必须满足user-initial-policy-set中的至少一个策略

    g) initial-any-policy-inhibit,表示是否允许处理证书中的anyPolicy OID

    h) initial-permitted-subtrees,表示每种name type(如X.500 distinguished names, email addresses, 或IP addresses)的子树的集合,如果证书路径中每个证书的subject名称都包含在该集合中,则会继续路径校验。initial-permitted-subtrees的输入包含每个name type的集合。对于每个name type,该类型的集合可能在一个子树中包含它所有的names或在多个子树中包含它的names的一个子集,或者该集合为空。如果某个name type的集合为空,而证书路径的某些证书包含该name type的name,则认为该证书路径无效。

    i) initial-excluded-subtrees,表示每种name type(如X.500 distinguished names, email addresses, 或IP addresses)的子树的集合,如果证书路径中没有证书的subject名称包含在该集合中,则会继续路径校验。initial-excluded-subtrees的输入包含每个name type的集合。对于每个name type,该集合可能为空或包含一个或多个子树,每个子树包含它的names的一个子集。如果某个name type的集合为空,则该name type的names都不会被排除。

    实现中并不要求支持所有的输入配置,如实现中,可能会使用initial-any-policy-inhibit为FALSE的值来校验所有的证书路径。

     6.1.2. Initialization

    根据上述9个输入,初始化阶段建立了12个状态变量(为内部状态变量,不体现在证书中):

    a) valid_policy_tree:(带有可选qualifier的)证书策略树,每个叶子表示本证书路径校验阶段的有效策略。如果证书路径校验中存在有效的策略,则树的深度与已经处理的证书链上的证书数目相同,如果本证书路径校验中不存在有效的策略,则该树被设置为NULL,一旦树被设置为NULL,将会停止处理策略。valid_policy_tree中的每个节点(node)包含3个数据对象:有效的策略,相关的策略qualifiers集合以及一个或多个策略值的集合。如果node的深度为x,node有如下语法:

    1. valid_policy,为一个策略OID,表示路径长度为x的有效策略
    2. qualifier_set,证书x中的有效策略相关的qualifiers集合
    3. expected_policy_set,中满足证书x+1的策略的一个或多个策略OIDs集合

    valid_policy_tree的初始值为valid_policy等于anyPolicy,qualifier_set为空,expected_policy_set为单个anyPolicy。该节点的深度为0。下图表示初始状态的valid_policy_tree。初始的node节点信息如下:

    b) permitted_subtrees:每种name type(如X.500 distinguished names, email addresses, 或IP addresses)的root names的集合,包含一个子树的集合,如果后续证书的subject名称都包含在该集合中,则会对该路径进行校验。该变量包含每个name type的集合,初始值为initial-permitted-subtrees

    c) excluded_subtrees:每种name type(如X.500 distinguished names, email addresses, 或IP addresses)的root names的集合,包含一个子树的集合,如果后续证书的subject名称都不包含在该集合中,则会对该路径进行校验。该变量包含每个name type的集合,初始值为initial-excluded-subtrees

    d) explicit_policy:整数,表示需要一个非NULL的valid_policy_tree 。该整数表示在该需求实施前的非自发证书的数目。一旦设置,该变量可能会减少,不可能增加。即如果路径中的证书需要一个非NULL的valid_policy_tree时,后续的证书无法移除该需求。如果设置了initial-explicit-policy,则初始值为0,否则为n+1

    e) inhibit_anyPolicy,整数,表示是否匹配anyPolicy策略的OID。整数表示在anyPolicy OID前处理的非自发证书的数目。如果出现在非中间自发证书中,则会被忽略。一旦设定,该变量可能会减少,不可能增加。当路径中的证书禁止处理anyPolicy时,后续的证书无法也无法处理。如果设置了initial-any-policy-inhibit,则初始值为0,否则初始值为n+1(即都允许处理)。

    f) policy_mapping:整数,表示是否允许policy mapping。整数表示在policy mapping禁止前处理的非自发证书的数目。如果出现在非中间自发证书中,则会被忽略。一旦设定,该变量可能会减少,不可能增加。即如果路径中的证书禁止处理policy mapping时,后续的证书无法也无法处理。如果设置了initial-policy-mapping-inhibit,则初始值为0,否则初始值为n+1

    g) working_public_key_algorithm:用于校验证书签名的数字签名算法。working_public_key_algorithm使用信任锚信息中的信任的public key进行初始化

    h) working_public_key:用于校验证书签名的public key。working_public_key使用信任锚信息中的信任的public key算法进行初始化

    i) working_public_key_parameters:当前用于校验证书签名(依赖于算法)的public key相关的参数,working_public_key_parameters使用信任锚信息中的信任的public key参数进行初始化

    j) working_issuer_name:证书链中期望的下一个证书的issuer DN。working_issuer_name使用信任锚信息中的信任的issuer名称进行初始化

    k) max_path_length:整数,初始化为n。随路径中的非自签证书递减,可能会缩小到CA证书的basic constraints扩展中path length constraint字段的值。

     6.1.3. Basic Certificate Processing

    对证书i(i in [1..n])的基本路径处理动作如下:

    a) 校验基本的证书信息,证书必须满足下面所有条件:

    1. 证书签名可以使用working_public_key_algorithm,working_public_key和working_public_key_parameters进行验证。
    2. 证书有效周期包含当前时间
    3. 当前时间下,证书没有被吊销。可以通过状态信息或带外机制获取CRL信息
    4. 证书issuer名称等于working_issuer_name

    b)  如果证书i是自签证书,且不是路径的最终证书,则忽略对证书i的这一步的处理。否则,校验该证书的subject name存在对应X.500 DN的permitted_subtrees中,并校验该证书的subjectAltName扩展(critical或非critical)中的每个alternative name存在对应name type的某个permitted_subtrees中。

    c)  如果证书i是自签证书,且不是路径的最终证书,则忽略对证书i的这一步的处理。否则,校验该证书的subject name不存在对应X.500 DN的excluded_subtrees中,并校验该证书的subjectAltName扩展(critical或非critical)中的每个alternative name不存在对应name type的任何excluded_subtrees中。

    d) 如果证书中出现了policies扩展且valid_policy_tree非NULL,通过如下步骤处理策略:

    1. 对于证书的policies扩展中不等于anyPolicy的策略P,P-OID表示策略P的OID,P-Q表示策略P设置的qualifier集合,按顺序执行以下步骤:

    (i) 对于valid_policy_tree中深度为n-1且P-OID存在于expected_policy_set的节点,按照如下方式生成子节点:将valid_policy设置为P-OID,将qualifier_set设置为P-Q,将expected_policy_set设置为{P-OID}

    例如,对于valid_policy_tree中一个node的深度为i-1,且expected_policy_set为{Gold,White},证书i的policies扩展中包含的策略为Gold和Silver。此时匹配到Gold策略,但没有匹配到Silver策略。该规则会为Gold 策略生成一个深度为i的子节点(策略树的深度与已处理证书的数目相同),如下图所示:

    (ii) 如果步骤(i)中没有匹配到任何策略,且valid_policy_tree包含一个深度为i-1,valid_policy为anyPolicy的节点,使用如下值生成子节点:将valid_policy设置为P-Q,qualifier_set设置为P-OID,expected_policy_set设置为{P-OID}。

    例如,对于valid_policy_tree中一个深度为i-1,valid_policy为anyPolicy的节点,证书i的policies扩展中包含的策略为Gold和Silver。Gold策略没有qualifier,且Silver的qualifier为Q-Silver。如果Gold和Silver没有都没有匹配到步骤(i) ,则规则会生成2个深度为i的子节点。

     

    2. 如果证书policies扩展中包含策略anyPolicy且qualifier集合为AP-Q,此时要么(a)inhibit_anyPolicy >0 或(b)证书是自(self-issued)的,然后进行如下步骤:

    对于valid_policy_tree中深度为i-1的节点,其expected_policy_set中的值(含anyPolicy)均不存在于它的子节点,使用如下值生成子节点:将valid_policy设置为父节点的expected_policy_set,将qualifier_set设置为P-Q,将expected_policy_set设置为该节点的valid_policy。

    例如,对于valid_policy_tree中一个深度为i-1,expected_policy_set为{Gold, Silver}的节点,假设证书i中的policies扩展出现了anyPolicy且没有任何qualifications,也没有Gold和Silver,使用如下规则生成深度为i的节点的每个策略

    3. 如果valid_policy_tree中一个深度为i-1或小于i-1的节点没有任何子节点,则删除该节点。重复该操作,直到没有深度为i-1的节点不含子节点。

    例如,考虑下图的valid_policy_tree。标记为"X"且深度为i-1的2个节点没有子节点,则删除这2个节点。将该规则应用到前面操作的结果中,则会导致标记为"Y",且深度为i-2的节点被删除。在最终的结果中,深度为i-1或小于i-1的节点不存在没有子节点的情况,则结束该步骤。

    (e) 如果没有出现policies扩展,则设置valid_policy_tree为NULL

    (f ) 验证explicit_policy大于0或valid_policy_tree不等于NULL

    如果(a), (b), (c)或 (f)失败,则终止该过程,返回失败和失败原因

    如果i 不等于n({1, ..., n}),则继续执行Section 6.1.4,反之执行Section 6.1.5

    6.1.4. Preparation for Certificate i+1

    为了处理证书i+1,对证书i执行如下步骤:

    a) 如果存在policy mapping扩展,验证anyPolicy不存在issuerDomainPolicy或subjectDomainPolicy中

    b) 如果存在policy mapping扩展,对于该扩展中的issuerDomainPolicy ID-P:

    1. 如果policy_mapping 变量大于0,对于valid_policy_tree中深度为i且valid_policy为ID-P的节点,将expected_policy_set设置为policy mappings扩展中subjectDomainPolicy值为ID-P的集合

    如果valid_policy_tree不包含深度为i且valid_policy为ID-P的节点,但包含valid_policy为anyPolicy的节点,使用如下方式为深度为i-1的(且valid_policy为anyPolicy)节点生成子节点

    (i)   将valid_policy 设置为ID-P
    (ii)  将qualifier_set设置为证书i的policies扩展中策略为anyPolicy的qualifier_set
    (iii) 将expected_policy_set设置为policy mappings扩展中subjectDomainPolicy值为ID-P的集合

    2. 如果policy_mapping等于0

    (i)  删除valid_policy_tree深度为i且valid_policy为ID-P的节点
    (ii) 如果valid_policy_tree中一个深度为i-1或小于i-1的节点没有任何子节点,则删除该节点。重复该操作,直到没有深度为i-1的节点不含子节点。

    c) 将证书的subject名称分配给working_issuer_name

    d) 将证书的subjectPublicKey分配给working_public_key

    e) 如果证书的subjectPublicKeyInfo字段包含非空参数的algorithm字段,将这些参数分配给working_public_key_parameters

    如果证书的subjectPublicKeyInfo字段包含空参数或参数被忽略的的algorithm字段,则将subjectPublicKey算法和working_public_key_algorithm进行比对,如果证书的subjectPublicKey算法和working_public_key_algorithm不同,则将working_public_key_parameters 设置为null

    f ) 将证书的subjectPublicKey algorithm分配给working_public_key_algorithm

    g) 如果证书存在name constraints扩展,使用如下规则修改permitted_subtrees和excluded_subtrees 状态变量

    1. 如果证书出现permittedSubtrees,将permitted_subtrees状态变量设置为它先前的值和证书扩展中的值的交集。如果permittedSubtrees不包含特定的name type,则不会改变该name type对应的permitted_subtrees状态变量。例如example.com和foo.example.com的交集为foo.example.com,example.com和example.net的交集为空

    2. 如果证书出现excludedSubtrees ,将excluded_subtrees状态变量设置为它先前的值和证书扩展中的值的并集。如果excludedSubtrees不包含特定的name type,则不会改变该name type对应的excluded_subtrees状态变量。例如example.com和foo.example.com的并集为example.com,example.com和example.net的并集为它们两个的name space

    h) 如果证书i非自发

    1. 如果explicit_policy非0,则explicit_policy-1

    2. 如果policy_mapping非0,则policy_mapping-1

    3. 如果inhibit_anyPolicy 非0,则inhibit_anyPolicy-1

    i) 如果证书出现policy constraints扩展,使用如下方式修改explicit_policy和policy_mapping状态变量

    1. 如果出现requireExplicitPolicy且小于explicit_policy,则将explicit_policy 设置为requireExplicitPolicy

    2. 如果出现inhibitPolicyMapping且小于policy_mapping,则将policy_mapping设置为inhibitPolicyMapping

    j) 如果证书包含inhibitAnyPolicy扩展,且inhibitAnyPolicy小于inhibit_anyPolicy,则将inhibit_anyPolicy设置为inhibitAnyPolicy

    k) 如果证书i为版本3的证书,校验存在basicConstraints扩展且cA设置为TRUE(如果证书i为版本1或版本2,则应用必须使用带外方法校验证书i为CA证书或拒绝该证书。相应的实现可能会拒绝所有版本1和版本2的中间证书)。

    l) 如果证书非自发的,校验max_path_length大于0,并使max_path_length -1

    m) 如果证书存在pathLenConstraint且小于max_path_length,则将max_path_length设置为pathLenConstraint

    n) 如果出现key usage扩展,校验keyCertSign 比特位置位。

    o) 识别并处理证书中出现的所有critical扩展。证书中非critical扩展的处理与特定的路径处理相关

    如果(a), (k), (l), (n),或 (o)失败,则终止处理,并返回失败状态和失败原因

    如果(a), (k), (l), (n), 和(o)成功,增加i的值,并执行Section 6.1.3

    6.1.5. Wrap-Up Procedure

    为了完成目标证书的处理,为证书n执行如下步骤:

    a) 如果explicit_policy非0,则explicit_policy -1

    b) 如果证书包含policy constraint扩展且requireExplicitPolicy 为0,则设置explicit_policy状态变量为0.

    c) 将working_public_key设置为证书的subjectPublicKey

    d) 如果证书的subjectPublicKeyInfo字段的algorithm字段包含非null的参数,则将working_public_key_parameters设置为这些参数

    如果证书的subjectPublicKeyInfo字段包含空参数或参数被忽略的的algorithm字段,则将subjectPublicKey算法和working_public_key_algorithm进行比对,如果证书的subjectPublicKey算法和working_public_key_algorithm不同,则将working_public_key_parameters 设置为null

    e) 将working_public_key_algorithm 设置为证书的subjectPublicKey algorithm

    f ) 识别并处理证书n中出现的所有critical扩展。证书中非critical扩展的处理与特定的路径处理相关

    g) 计算valid_policy_tree和user-initial-policy-set的交集,如下:

    (i) 如果valid_policy_tree为NULL,交集为NULL
    (ii) 如果valid_policy_tree非NULL,且user-initial-policy-set为any-policy,交集为valid_policy_tree
    (iii) 如果valid_policy_tree非NULL,且user-initial-policy-set为非any-policy,交集使用如下方式计算

    1. 父节点的valid_policy为anyPolicy的策略节点的集合即valid_policy_node_set
    2. 如果valid_policy_node_set中的所有节点的valid_policy都不在user-initial-policy-set中且不是anyPolicy,则删除该节点以及该节点的子节点
    3. 如果valid_policy_tree包含一个深度为n,且valid_policy为anyPolicy,user-initial-policy-set为非anyPolicy的节点,则执行如下步骤

    a. 将P-Q设置为深度为n,valid_policy为anyPolicy的节点的qualifier_set

    b. 如果user-initial-policy-set中的每个P-OID都不是valid_policy_node_set中的节点的valid_policy,则创建一个父节点为深度为n-1且valid_policy为anyPolicy的子节点。子节点的值设置如下:将valid_policy设置为P-Q,将qualifier_set设置为P-Q, 将expected_policy_set设置为{P-OID}

    c. 删除深度为n且valid_policy为anyPolicy的节点

    4. 如果valid_policy_tree中深度为n-1或小于n-1的节点没有任何子节点,则删除该节点,直到没有深度为i-1的节点不含子节点。
    如果(1)explicit_policy变量的值大于0或(2)valid_policy_tree 非NULL,则路径处理成功

     如果(1)explicit_policy变量的值大于0或(2)valid_policy_tree 非NULL,则路径处理成功

    6.1.6. Outputs

    如果路径处理成功,则结束该过程,返回成功和valid_policy_tree中的最后一个数值,以及working_public_key,working_public_key_algorithm和working_public_key_parameters

    6.2. Using the Path Validation Algorithm

    路径校验算法描述了校验一条证书路径的过程。由于每条证书路径以某个特定的信任锚开始,因此没有要求要使用特定的信任锚来校验所有的证书路径。是否采用一个或多个trusted CA由本地决定。一个系统可能会提供任何一个trusted CA作为路径校验的信任锚。每条证书路径校验的输入都可能不同,路径处理中的输入反映了应用的特殊需求或限制了某个信任锚的授权范围。如,一个trusted CA可能仅仅信任特定的证书策略。该限制通过证书路径处理的输入来表达。

    实现中可能会修改Section 6.1出现的算法来限制使用特定信任锚开始的证书路径的集合。例如,实现中可能修改算法来在初始化阶段限制使用特定信任锚的路径的长度,或者应用可能会要求在目标证书中出现特定的alternative name type,或者应用可能强制要求应用制定的扩展。因此Section 6.1中的路径校验算法仅仅给出了路径校验的最基础条件。

    当CA使用自签证书来指定信任锚信息时,证书扩展可以用来指定推荐的路径校验的输入。例如,policy constraints扩展可能会包含在自签证书中,用于指定作为路径开始的信任锚仅仅信任特定的策略。类似地,包含的name constraints可能用于指定作为路径开始的信任锚仅仅信任特定的name spaces。Section 6.1中出现的路径校验算法没有假设信任锚信息由自签证书提供,且没有指明对这类证书的额外信息的处理规则。使用自签证书作为信任锚信息时,在处理过程中可以忽略这些信息。

     TIPS:

    • 可以使用openssl verify -CAfile $CA.CRT $MY.CRT命令验证证书发布
    • 证书路径的存在是沿着证书路径找到一个可信的CA
    • 当浏览器校验证书时,会校验证书的有效性,以及证书持有者的有效性。前者通过证书路径校验,后者通过校验浏览器输入的域名或IP是否在证书中的SAN/SN中。服务器证书最好使用域名,否则如果仅使用IP,在https代理场景下会出现认证问题(NAT会改变IP地址)。

    参考:

    https://tools.ietf.org/html/rfc5280

    https://www.juniper.net/documentation/en_US/junos/topics/topic-map/security-digital-certificates-with-pki-overview.html

  • 相关阅读:
    Git配置文件
    Python操作Excel表格概括
    字符串时间转换为格式化时间
    windows 安装pip 及更换pip国内源
    JS数组遍历的方法汇总
    python文件读写操作(r/r+/rb/w/w+/wb/a/a+/ab)
    【Offer】Kafka面试题总结
    netdata开源Linux系统监控系统安装:配置项详解
    netdata开源Linux系统监控系统安装:一句话满足你的要求
    nginx配置禁特定路径下的反向代理
  • 原文地址:https://www.cnblogs.com/charlieroro/p/10948173.html
Copyright © 2020-2023  润新知