X.509公钥证书

X.509公钥证书

X.509最初由ITU-T用于X500目录服务中,对X.500实体的身份进行验证,所以X.509使用了一些X500中的元素。
后来IETF PKIX工作组对X.509进行了扩展和补充,使更好的用于互联网环境中。目前X.509已经是独立的标准,最新版本为X.509 V3,而且X.509是TLS中唯一受支持的证书标准。关于X.509 V3的定义可参考rfc5280。

  1. X.509证书的语法格式和序列化

X.509证书的格式格式定义和序列化都使用了ASN.1标准。X.509的语义描述使用ASN.1代码,而ASN.1的序列化编码有BER,DER,PEM。BER和DER都是二进制编码,BER编码有些地方存在歧义或者对编码结果没有严格约束,而DER则是BER的strict版本,确保一个ASN.1代码序列化后的二进制是唯一的,而不会出现不同实现结果不一样的情况。X.509证书的序列化就是用的DER格式,而PEM编码则是到DER进一步进行Base64处理。
理解ASN.1后再看RFC5280标准文档就容易多了。

  1. 密码算法

    X.509证书涉及到了非对称加密,Hash,对称加密等加密算法,学习X.509证书需要有这方面的知识储备。

  2. X.509的ASN.1定义

Certificate  ::=  SEQUENCE  {
    tbsCertificate       TBSCertificate,
    signatureAlgorithm   AlgorithmIdentifier,
    signature            BIT STRING  }
TBSCertificate  ::=  SEQUENCE  {
    version         [0]  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]  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
    }

这个ASN.1代码是RFC5280定义的,描述了X.509证书的基本字段(省略了扩展字段)
下面是CRL的定义

CertificateList  ::=  SEQUENCE  {
    tbsCertList          TBSCertList,
    signatureAlgorithm   AlgorithmIdentifier,
    signature            BIT STRING  }

TBSCertList  ::=  SEQUENCE  {
    version                 Version OPTIONAL,
                                -- if present, MUST be v2
    signature               AlgorithmIdentifier,
    issuer                  Name,
    thisUpdate              Time,
    nextUpdate              Time OPTIONAL,
    revokedCertificates     SEQUENCE OF SEQUENCE  {
        userCertificate         CertificateSerialNumber,
        revocationDate          Time,
        crlEntryExtensions      Extensions OPTIONAL
                                -- if present, version MUST be v2
                            }  OPTIONAL,
    crlExtensions           [0] Extensions OPTIONAL }
                                -- if present, version MUST be v2

-- Version, Time, CertificateSerialNumber, and Extensions were
-- defined earlier for use in the certificate structure

AlgorithmIdentifier  ::=  SEQUENCE  {
    algorithm               OBJECT IDENTIFIER,
    parameters              ANY DEFINED BY algorithm OPTIONAL  }
                                -- contains a value of the type
                                -- registered for use with the
                                -- algorithm object identifier value

只要理解上面各个字段的函义,证书的定义就完全掌握了。
其中tbsCertList包含了证书主体,除了签名以外的内容全在这里面。

  1. 字段详解

4.1. version字段

0表示Version1,1表示Version2,2表示Version3

4.2. serialNumber字段

签发证书时的序列号,每次递增,用正整数表示。同一个CA签发的证书不能重复。

4.3. signature

这个定义的是签名算法。

4.4. issuer

证书发行方的DN,自签名证书这一项与subject相同

4.5. validity

证书书的有效期,ASN.1类型定义是UTC Time

4.6. subject

证书主题的DN,主题代表证书所代表的实体,也就是这个证书的持有人。

4.7. subjectPublicKeyInfo

主题的公钥信息,包含算法类型和公钥的Bit流数据

4.8. issuerUniqueID和subjectUniqueID

这是X.509 V2中增加的字段,issuer和subject的值是用唯一标识符表示的,RFC5280中并没有说UniqueID的长度和生成规则,而且这两个字段已很少使用。

4.9. extensions

这个就是在TLS X.509证书中常说的V3扩展,是在X.509V3中新增的字段,也是最复杂的一个字段。在RFC5280中的4.2节专门禅述了这个字段。
ASN.1定义

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
    }

extnID 是一个oid,标识扩展的类型
critical 标识该扩展是否是关键的
extnValue 扩展的值,按照ASN.1格式定义

这里只说在X.509中定义的标准扩展。

4.9.1. Authority Key Identifier

签发当前证书所用公钥的指纹,一个issuer可能有多个公钥。指纹是用160-bit SHA-1计算的。在ASN.1中用属性名authorityKeyIdentifier表示。
自签名证书这一项可忽略

4.9.2. Subject Key Identifier

主题公钥标识符,就是证书自己的公钥指纹了

4.9.3 Key Usage

Key Usage是一个bit开关字段,指定证书的用途。CA证书中KeyUsage是必选的。
ASN.1定义如下:

      id-ce-keyUsage OBJECT IDENTIFIER ::=  { id-ce 15 }

      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) }

digitalSignature 数据签名和验证(不包括证书和CRL)
nonRepudiation 不可否认性,签名和验证数据(不包括证书和CRL)时提供不可否认性(具有法律效力)
keyEncipherment 密钥加密
dataEncipherment 使用RSA公钥进行数据加密,很少使用
keyAgreement 密钥协商,如DH协议
keyCertSign 证书签名和验证,CA证书这一位必须为1
cRLSign CRL(证书吊销列表)签名和验证
encipherOnly 密钥协商时加密数据,需要与keyAgreement一起使用
decipherOnly 密钥协商时解密数据,需要与keyAgreement一起使用

4.9.4. Certificate Policies

证书策略指示证书的使用规范

ASN.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)) }

由以上ASN.1代码可看出CertPolicyId都是由OID表示的。
定义很长,但实际上关键的就两个cPSuri和userNotice。cPSuri是一个URL,指向证书的使用规范,可以是html或pdf。userNotice是通知文本,相当于证书的使用公告或通知。X.509定义的证书策略就这两个,但是CA/Browser Forum还定义了以下TLS证书策略。

策略OID 描述
2.23.140.1.1 Extended Validation Certificate Policy
2.23.140.1.2.1 Domain Validation Certificates Policy
2.23.140.1.2.2 Organization Validation Certificates Policy

这三项分别是EV,DV,OV证书策略,在TLS证书中至少要有一个。
完整的策略可以参考这里:
https://cabforum.org/resources/object-registry/
https://www.globalsign.com/en/repository/GlobalSign-CP-v7.4-final.pdf

4.9.5. Policy Mappings

当不同组织的CA交叉认证的时候,因为两个组织有不同的CP(Certificate Policies)定义,但是有些CP又是类似的,这时候就可以使用Policy Mappings把一个组织中的CP映射到另一个组织。
ASN.1定义

   id-ce-policyMappings OBJECT IDENTIFIER ::=  { id-ce 33 }


   id-ce-policyMappings OBJECT IDENTIFIER ::=  { id-ce 33 }


   PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE {
        issuerDomainPolicy      CertPolicyId,
        subjectDomainPolicy     CertPolicyId }

issuerDomainPolicy 外部组织的CP
subjectDomainPolicy 本组织的CP
其中CertPolicyId就是策略的OID值。

4.9.6. Subject Alternative Name

Subject Alternative Name,顾名思义就是用来替代subject的DN的,如果存在Subject Alternative Name时subject的DN允许为空,但是Subject Alternative Name要标记critical。
ASN.1定义

   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 }

由ASN.1代码可见SubjectAltName所允许的值非常宽泛,可以是域名,ip地址,DN,邮件地址或者其它的任何名字,甚至还可以是通配符”*”。在TLS证书中通常是域名或IP地址。

4.9.7. Subject Directory Attributes

Subject的一个或多个Directory属性,属于非关键字段,这个应该主要用于LDAP/X500了。
ASN.1定义

“`ASN.1
id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }

id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 }

SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute

<pre><code class="line-numbers">4.9.8. Basic Constraints

标识当前证书是否为CA以及自当前证书开始允许的证书链长度(pathLenConstraint),只为证书为CA时证书链长度约束才有效。
ASN.1定义
“`ASN1
BasicConstraints ::= SEQUENCE {
cA BOOLEAN DEFAULT FALSE,
pathLenConstraint INTEGER (0..MAX) OPTIONAL }

cA 指示是否为CA
pathLenConstraint 自当前证书开始,允许的证书链长度

4.9.9. Name Constraints

用于限制CA签发证书时subject和Subject Alternative Name属性的值,这样就能限制CA只能为指定的域名签发证书。
只有CA才有NameConstraints字段,而且自签名CA没有这个字段。

“`ASN.1
id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 }

<pre><code> 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)
</code></pre>

<pre><code class="line-numbers">4.9.10. Policy Constraints

在证书链中限制证书策略和策略映射,用于CA证书。

ASN.1定义
“`ASN1

id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 }

PolicyConstraints ::= SEQUENCE {
requireExplicitPolicy [0] SkipCerts OPTIONAL,
inhibitPolicyMapping [1] SkipCerts OPTIONAL }

SkipCerts ::= INTEGER (0..MAX)

requireExplicitPolicy 指示证书链中多少个证书以后必须声明政书策略
inhibitPolicyMapping 指示证书链中多少个证书以后不能指定策略映射

4.9.11. Extended Key Usage

这个字段是对Key Usage的扩展,增加了更多Key Usage定义。
不同于Key Usage用状态字来定义,Extended Key Usage是用OID来定义的。

   id-ce-extKeyUsage OBJECT IDENTIFIER ::= { id-ce 37 }

   ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId

   KeyPurposeId ::= OBJECT IDENTIFIER

   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

对于TLS服务器证书必须包含id-kp-serverAuth

4.9.12. CRL Distribution Points

指定CRL文件的位置,这是个非关键字段。

   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) }

distributionPoint http或ldap url,用于下载crl文件,可以有多个
reasons 证书吊销的原因
cRLIssuer CRL文件的签发者的DN,CRL和证书签发人不一样时才需要
4.9.13. Inhibit anyPolicy

限制anyPolicy的生效,也算一种策略约束

   Conforming CAs MUST mark this extension as critical.

   id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::=  { id-ce 54 }

   InhibitAnyPolicy ::= SkipCerts

   SkipCerts ::= INTEGER (0..MAX)

SkipCerts 指定证书链中多少个证书以后anyPolicy策略不再生效

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

增量CRL分发点,语法跟CRL Distribution Points一样

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

   FreshestCRL ::= CRLDistributionPoints

4.9.15. Authority Information Access

授权信息访问,就是签发人(CA)的可访问的在线信息

   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 }

id-ad-caIssuers 指示证书链中各个上级CA的链接,用于对证书链进行验证。这个字段可以多次出现。
id-ad-ocsp CA的ocsp(Online Certificate Status Protocol)链接,维护证书的吊销状态

4.9.16. Subject Information Access

主题信息访问,就是证书持有人的可访问的在线信息,当subject是CA时这个扩展才存在

   id-ad OBJECT IDENTIFIER ::= { id-pkix 48 }

   id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 }

   id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 }

id-ad-caRepository 证书仓库,就是CA签发证书后会放在这个仓库中,可以从这里下载证书
id-ad-timeStamping TSP(Time-Stamp Protocol)协议服务地址,TSP用于对时间进行签名,时间的签名信息是从TSP在线获取的。

  1. 签名

5.1. signatureAlgorithm

签名算法,与TBSCertificate.signature的值相同

5.2. signature

证书的具体签名信息

  1. 名词解释

6.1. DN

一个DN(distinguished name)是由多个RDN(relative distinguished name)组成的,DN中的一个字段就是一个RDN。在X500/LDAP中广泛使用。
这是LDAP/X.500用到的基本RDN字段
String X.500 AttributeType
—— ——————————————–
CN commonName (2.5.4.3)
L localityName (2.5.4.7)
ST stateOrProvinceName (2.5.4.8)
O organizationName (2.5.4.10)
OU organizationalUnitName (2.5.4.11)
C countryName (2.5.4.6)
STREET streetAddress (2.5.4.9)
DC domainComponent (0.9.2342.19200300.100.1.25)
UID userId (0.9.2342.19200300.100.1.1)
这些字段是在X500中定义的,参考RFC4514和RFC4519。
DN验证的时候忽略大小写和多余的空白符,DN必须支持UTF8。
这是X.509中用到的基本RDN字段,就是说这些字段是必须实现的。
* country,
* organization,
* organizational unit,
* distinguished name qualifier,
* state or province name,
* common name (e.g., “Susan Housley”), and
* serial number.

必须实现的附加字段

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

X.509中还必须实现domainComponent字段,domainComponent是LDAP中的DC(域给件),不是DNS中的域名,详细介绍可以看LDAP/X.500。
因为有些系统使用DN名作为认证方法,所以DN的比较也是很重要的。
RFC5280中分为了三种情况,
– DN1和DN2的RDN数量相同,则DN1中的每个字段都能在DN2中找到相同的字段则认为DN1与DN2相同
– DN1和DN2的RDN数量相同,顺序也相同,并且则DN1中的每个字段都能在DN2中找到相同的字段则认为DN1与DN2相同
– DN1和DN2的RDN数量不同,则把较长的DN1从尾部把多余的RDN去掉,然后按前面的方法进行比较。DN的定义是大的单位在前面,小的单位在后面,所以这样等于DN1是否属于DN2的下属单位。

对于两个不同的实体DN不能相同,但是一个实体可以有多个DN。
在LDAP中DN是用于对目录名(DirectoryName)进行标识的。

6.2. Subject

代表持有证书的实体,可以是最实体,也可以是CA。

6.3. Issuer

代表签发证书的实体,一定是CA

参考:

RFC5280

发表回复