英文原文:https://blog.csdn.net/blue0bird/article/details/78656536
https://jamielinux.com/docs/openssl-certificate-authority/index.html
本文源于两篇英文文档,将其合二为一,翻译过程参考了网上的其它翻译以求更加准确,再此对这些翻译文档的作者表示感谢!
文中介绍的OpenSSL版本较老,与现有的版本有很多不符之处,但万变不离其宗,核心原理还是很有参考价值的。
X.509标准是密码学里公钥证书的格式标准。X.509 证书己应用在包括TLS/SSL(WWW万维网安全浏览的基石)在内的众多 Internet协议里,同时它也有很多非在线的应用场景,比如电子签名服务。X.509证书含有公钥和标识(主机名、组织或个人),并由证书颁发机构(CA)签名(或自签名)。对于一份经由可信的证书签发机构签名(或者可以通过其它方式验证)的证书,证书的拥有者就可以用证书及相应的私钥来创建安全的通信,以及对文档进行数字签名。
X.509最早与X.500一起发布于1988年7月3日,它假定颁发证书的证书颁发机构(CA)具有严格的层次结构。这与Web信任模型(如PGP)形成了鲜明对比,因为PGP方案是任何人都以签名(而不仅仅是地位特殊的CA),从而证明其他人的密钥证书的有效性。X.509 V3证书的设计非常灵活,除了对网桥拓扑架构网络的支持,还可以支持用于点对点方式的Mesh网,类似于OpenPGP那样的web信任机制,不过这样方式在2004年之前很少使用。
X.500系统仅由主权国家实施,以实现国家身份信息共享条约的实施目的,而IETF的公钥基础设施(X.509)或PKIX工作组已对该标准进行了调整,以适应更灵活的互联网组织结构。事实上X.509认证指的是RFC5280里定义的X.509 v3,包括对IETF的PKIX证书和证书吊销列表(CRL Profile),通常也称为公钥基础设施。
在X.509系统中,证书申请者通过发起“证书签名请求(CSR)”来得到一份被签名的证书。为此,它需要生成一个密钥对,然后用其中的私钥对CSR签名(私钥本身要妥善保存,对外保密),CSR包含申请人的身份信息、用于验真CSR的申请人的公钥,以及所请求证书的专有名称(DN),CSR还可能带有CA要求的其它有关身份证明的信息,然后CA对这个专有名称发布一份证书,并绑定一个公钥。
组织机构可以把受信的根证书分发给所有的成员,这样就可以使用公司的PKI系统了。像Firefox, IE, Opera, Safari 以及Google Chrome这些浏览器都预装了一组CA根证书,所以可以直接使用这些主流CA发布的SSL证书。浏览器的开发者直接影响它的用户对第三方的信任。FireFox就提供了一份csv/html格式的列表。
X.509还包括证书吊销列表(CRL)实现标准,这是PKI系统经常被忽略的方面。IETF批准的检查证书有效性的方法是在线证书状态协议(OCSP),Firefox 3默认情况下启用OCSP检查,从Vista开始的高版本Windows也是如此。
X.509证书的结构是用ASN.1(Abstract Syntax Notation One:抽象语法标记)来描述其数据结构,并使用ASN1语法进行编码。
X.509 v3数字证书的结构如下:
● Certificate 证书
● Version Number版本号
● Serial Number序列号
● ID Signature Algorithm ID签名算法
● Issuer Name颁发者名称
● Validity period 有效期
● Not before起始日期
● Not after截至日期
● Subject Name主题名称
● Subject pbulic Key Info 主题公钥信息
● Public Key Algorithm公钥算法
● Subject Public Key主题公钥
● Issuer Unique Identifier (optional)颁发者唯一标识符(可选)
● Subject Unique Identifier (optional)主题唯一标识符(可选)
● Extensions (optional) 证书的扩展项(可选)
…
● Certificate Sigature Algorithm证书签名算法
● Certificate Signature证书的签名
所有扩展都有一个ID,由object identifier来表达,它是一个集合,并且有一个标记指示这个扩展是不是决定性的。证书使用时,如果发现一份证书带有决定性标记的扩展,而这个系统并不清楚该扩展的用途,就要拒绝使用它。但对于非决定性的扩展,不认识可以予以忽略。RFC 1422给出了v1的证书结构,ITU-T在v2里增加了颁发者和主题唯一标识符,从而可以在一段时间后重用。重用的一个例子是当一个CA破产了,它的名称也在公共列表里清除掉了,一段时间之后另一个CA可以用相同的名称来注册,即使它与之前的并没有任何瓜葛。不过IETF并不建议重用同名注册。另外v2也没有在Internet里大范围的使用。v3引入了扩展,CA使用扩展来发布一份特定使用目的的证书(比如说仅用于代码签名)。
对于所有的版本,同一个CA颁发的证书序列号都必须是唯一的。
RFC 5280(及后续版本)定义了数字证书扩展项,用于指示如何使用证书。它们大多来自joint-iso-ccitt(2)ds(5)id-ce(29)OID。第4.2.1节中定义的一些最常见的是:
● Basic Constraints,{id ce 19},用于指示一份证书是不是CA证书。
● Key Usage, {id ce 15},指定了这份证书包含的公钥可以执行的密码操作,例如只能用于签名,但不能用来加密。
●Extended Key Usage{id ce 37},典型用法是指定叶子证书中的公钥的使用目的。它包括一系列的OID,每一个都指定一种用途。例如{id pkix 31}表示用于服务器端的TLS/SSL连接;{id pkix 34}表示密钥可以用于保护电子邮件。
通常情况下,当一份证书有多个限制用途的扩展时,所有限制条件都应该满足才可以使用。RFC 5280有一个例子,该证书同时含有keyUsage和extendedKeyUsage,这样的证书只能用在被这两个扩展指定的用途,例如网络安全服务决定证书用途时,会同时对这个扩展进行判断。
1-3)证书文件扩展名
X.509证书有几种常用的文件扩展名,但要注意:其中一些扩展名也有其它用途,就是说具有这个扩展名的文件可能并不是证书,比如说可能只是保存了私钥。
● .pem:(隐私增强型电子邮件),DER编码的证书再进行Base64编码,数据存放于“--- BEGIN CERTIFICATE ---”和“ --- END CERTIFICATE ---”之间
● .cer,.crt,.der:通常采用二进制DER形式,但Base64编码也很常见
● .p7b,.p7c-PKC#7:SignedData结构,没有数据,仅有证书或CRL
● .p12-PKCS#12:可以包含证书(公钥),也可同时包含受密码保护的私钥
● .pfx :PKCS#12的前身(通常用PKCS#12格式,例如IIS产生的PFX文件)
PKCS#7是签名或加密数据的格式标准,官方称之为容器。由于证书是可验真的签名数据,所以可以用SignedData结构表述。.P7C文件是退化的SignedData结构,没有包括签名的数据。
PKCS#12从个人信息交换(PFX)标准发展而来,用于在单个文件中交换公共和私有对象。
证书链(也就是RFC 5280里的证书路径)指的是以最终实体证书开头,后跟一个或多个CA证书,且通常最后一个是自签名证书,具有如下关系:
1.除了链上的最后一个证书外,每个证书的颁发者等于其后一个证书的主题(主题就是使用者)。
2.除了链上的最后一个证书外,每个证书都是由其后的一个证书签名。
3.最后一个证书是信任锚:由于是通过某种可信的过程得到的,所以你可以信任它。
证书链用来检查目标证书(链中的第一个证书)中包含的公钥和其他数据是否属于其主题。检查是这么做的,用证书链中的下一个证书的公钥来验证它的签名,一直检查到证书链的尾端,由于最后一个证书是信任锚,成功达到该证书将证明目标证书可以信任。
上段中的描述是根据RFC5280定义的认证路径验证过程的简化过程,实际上涉及额外的检查,例如验证证书的有效日期、查找CRL等。
在研究证书链的构建和验证方式时,需要特别注意的是,具体的证书可以是不同的证书链的一部分(链上的所有证书都有效)。 这是因为可以为相同的主题和公钥生成多个CA证书,但使用不同的私钥(来自不同的CA或来自同一CA的不同的私钥)进行签名。 因此,尽管单个X.509证书只能具有一个颁发者和一个CA签名,但是它可以有效地链接到多个证书,从而建立完全不同的证书链。 这对于PKI与其他应用程序之间的交叉认证至关重要,详见以下示例。
下图每个框代表一个证书,主题以粗体显示,A→B表示“ A由B签名”(或更准确地说,A由B包含公钥相对应的私钥签名),具有相同颜色(非白色/透明)的证书包含相同的公钥。
例1:两个PKI之间,在根证书颁发机构(CA)级别上进行交叉认证
为了让PKI 2的用户证书也得到PKI 1的信任,CA1签署包含CA2公钥的证书cert2.1,此时cert2和cert2.1具体相同的主题及公钥,cert2.2 (User 2)就有了两条合法的证书链:"cert2.2 → cert2" and "cert2.2 → cert2.1 → cert1"。
CA2也可以生成类似的包含有CA1公钥的证书cert1.1,以便PKI 1的用户(比如User 1)的证书能在PKI 2得到认证。
例2:CA证书更新
阅读这篇文章:了解认证路径构建(PDF,PKI论坛,2002)
证书颁发者为了从旧的私钥平滑地转移到新的私钥,他可以颁发两个证书,其中一个是新的私钥对旧的公钥进行签名,另一个是旧的私钥对新的公钥的签名,这两个证书都是自颁发的,但都不是自签名。注:另外还存在新旧两个自签名证书。
假设cert1和cert3包含相同的公钥(旧的公钥),对于cert5来说有两条合法的证书链,cert5 → cert1 和 cert5 → cert3 → cert2, cert6的情况也类似。这样就允许老的用户证书可以在新旧两个根证书之间平滑转移。
以下是维基百科网站Wikipedia.org和其他几家Wikipedia网站的X.509证书解码实例,由GlobalSign发布,它的颁发者字段(Subject)将Wikipedia描述为一个组织,Subject Alternative Name字段描述可以使用的主机名。Subject Public Key Info字段包含一个ECDSA公钥,而底部的签名由GlobalSign的RSA私钥生成。
3-1)最终实体证书
网摘:最终实体证书就是大家通常说的用户证书,有别于CA证书,最终实体证书中的证书主体是不能使用证书所对应的私钥签发证书的。最终实体与CA是两个相对的概念:CA可以利用其私钥签发证书,而最终实体不能。虽然在X.509标准中并未明确定义最终实体证书,但是定义了“最终实体公钥证书吊销列表 (End-entity public-key certificate revocation list)”的概念,由此可见最终实体证书就是指用户证书。最终实体可以是各种类型的实体,如自然人、组织机构、设备、Web服务器等。
Certificate: Data: Version: 3 (0x2) Serial Number: 10:e6:fc:62:b7:41:8a:d5:00:5e:45:b6 Signature Algorithm: sha256WithRSAEncryption Issuer: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2 Validity Not Before: Nov 21 08:00:00 2016 GMT Not After : Nov 22 07:59:59 2017 GMT Subject: C=US, ST=California, L=San Francisco, O=Wikimedia Foundation, Inc., CN=*.wikipedia.org Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:c9:22:69:31:8a:d6:6c:ea:da:c3:7f:2c:ac:a5: af:c0:02:ea:81:cb:65:b9:fd:0c:6d:46:5b:c9:1e: ed:b2:ac:2a:1b:4a:ec:80:7b:e7:1a:51:e0:df:f7: c7:4a:20:7b:91:4b:20:07:21:ce:cf:68:65:8c:c6: 9d:3b:ef:d5:c1 ASN1 OID: prime256v1 NIST CURVE: P-256 X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Agreement Authority Information Access: CA Issuers - URI:http://secure.globalsign.com/cacert/gsorganizationvalsha2g2r1.crt OCSP - URI:http://ocsp2.globalsign.com/gsorganizationvalsha2g2 X509v3 Certificate Policies: Policy: 1.3.6.1.4.1.4146.1.20 CPS: https://www.globalsign.com/repository/ Policy: 2.23.140.1.2.2 X509v3 Basic Constraints: CA:FALSE X509v3 CRL Distribution Points: Full Name: URI:http://crl.globalsign.com/gs/gsorganizationvalsha2g2.crl X509v3 Subject Alternative Name: DNS:*.wikipedia.org, DNS:*.m.mediawiki.org, DNS:*.m.wikibooks.org, DNS:*.m.wikidata.org, DNS:*.m.wikimedia.org, DNS:*.m.wikimediafoundation.org, DNS:*.m.wikinews.org, DNS:*.m.wikipedia.org, DNS:*.m.wikiquote.org, DNS:*.m.wikisource.org, DNS:*.m.wikiversity.org, DNS:*.m.wikivoyage.org, DNS:*.m.wiktionary.org, DNS:*.mediawiki.org, DNS:*.planet.wikimedia.org, DNS:*.wikibooks.org, DNS:*.wikidata.org, DNS:*.wikimedia.org, DNS:*.wikimediafoundation.org, DNS:*.wikinews.org, DNS:*.wikiquote.org, DNS:*.wikisource.org, DNS:*.wikiversity.org, DNS:*.wikivoyage.org, DNS:*.wiktionary.org, DNS:*.wmfusercontent.org, DNS:*.zero.wikipedia.org, DNS:mediawiki.org, DNS:w.wiki, DNS:wikibooks.org, DNS:wikidata.org, DNS:wikimedia.org, DNS:wikimediafoundation.org, DNS:wikinews.org, DNS:wikiquote.org, DNS:wikisource.org, DNS:wikiversity.org, DNS:wikivoyage.org, DNS:wiktionary.org, DNS:wmfusercontent.org, DNS:wikipedia.org X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication X509v3 Subject Key Identifier: 28:2A:26:2A:57:8B:3B:CE:B4:D6:AB:54:EF:D7:38:21:2C:49:5C:36 X509v3 Authority Key Identifier: keyid:96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C Signature Algorithm: sha256WithRSAEncryption 8b:c3:ed:d1:9d:39:6f:af:40:72:bd:1e:18:5e:30:54:23:35: ...
要验证此最终实体证书,需要一个与其颁发者和颁发机构密钥标识符(Authority Key Identifier)匹配的中间证书:
Issuer: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2 X509v3 Authority Key Identifier: keyid:96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C
在TLS连接中,作为握手过程的一部分,正确配置的服务器将提供该中间层,但也可以通过从最终实体证书中提取“ CA Issuers” URL来检索中间证书。
3-2)中间证书
网摘:什么是中间证书?
中间证书用作根证书的替代。我们使用中间证书作为代理,因为我们必须将根证书保存在众多安全层之后,以确保其密钥绝对不可访问。由于根证书签署了中间证书,因此中间证书可用于签署客户安装和维护的SSL“信任链”。
注意:如果不使用已颁发的SSL证书安装中间证书,则可能无法建立可信链证书。这意味着,当访问者试图访问您的网站时,他们可能会收到一个“安全警报”错误,指示“安全证书是由您未选择信任的公司颁发的…”面对这样的警告,潜在客户很可能会将其业务转移到其他地方。
以下是中间证书的实例,此证书被CA根证书签署,并签署了上面的最终实体证书。
注意:此中间证书的subject字段与它所签署的最终实体证书的issuer字段相同、中间证书的subject key identifier(主题密钥标识符)字段与最终实体证书的的authority key identifier(颁发者的密钥标识符)字段相同。
Certificate: Data: Version: 3 (0x2) Serial Number: 04:00:00:00:00:01:44:4e:f0:42:47 Signature Algorithm: sha256WithRSAEncryption Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA Validity Not Before: Feb 20 10:00:00 2014 GMT Not After : Feb 20 10:00:00 2024 GMT Subject: C=BE, O=GlobalSign nv-sa, CN=GlobalSign Organization Validation CA - SHA256 - G2 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:c7:0e:6c:3f:23:93:7f:cc:70:a5:9d:20:c3:0e: ... Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Certificate Sign, CRL Sign X509v3 Basic Constraints: critical CA:TRUE, pathlen:0 X509v3 Subject Key Identifier: 96:DE:61:F1:BD:1C:16:29:53:1C:C0:CC:7D:3B:83:00:40:E6:1A:7C X509v3 Certificate Policies: Policy: X509v3 Any Policy CPS: https://www.globalsign.com/repository/ X509v3 CRL Distribution Points: Full Name: URI:http://crl.globalsign.net/root.crl Authority Information Access: OCSP - URI:http://ocsp.globalsign.com/rootr1 X509v3 Authority Key Identifier: keyid:60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B Signature Algorithm: sha256WithRSAEncryption 46:2a:ee:5e:bd:ae:01:60:37:31:11:86:71:74:b6:46:49:c8: ...
3-3)根证书
以下是证书颁发机构的自签名根证书示例,Issuer(颁发者字段)和Subject(主题,使用者字段)是相同的,能够使用自己的公钥对签名进行验证,信任链的验证必须在此结束。如果验证程序在其信任存储中有此根证书,就可以认为在TLS连接中使用的最终实体证书是可信的。否则,最终实体证书被视为不可信。
Certificate: Data: Version: 3 (0x2) Serial Number: 04:00:00:00:00:01:15:4b:5a:c3:94 Signature Algorithm: sha1WithRSAEncryption Issuer: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA Validity Not Before: Sep 1 12:00:00 1998 GMT Not After : Jan 28 12:00:00 2028 GMT Subject: C=BE, O=GlobalSign nv-sa, OU=Root CA, CN=GlobalSign Root CA Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:da:0e:e6:99:8d:ce:a3:e3:4f:8a:7e:fb:f1:8b: ... Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Certificate Sign, CRL Sign X509v3 Basic Constraints: critical CA:TRUE X509v3 Subject Key Identifier: 60:7B:66:1A:45:0D:97:CA:89:50:2F:7D:04:CD:34:A8:FF:FC:FD:4B Signature Algorithm: sha1WithRSAEncryption d6:73:e7:7c:4f:76:d0:8d:bf:ec:ba:a2:be:34:c5:28:32:b5:
Bruce Schneier,Peter Gutmann和其他安全专家发表了许多有关PKI问题的出版物。
4-1)架构缺陷
将无效的证书列入黑名单(使用CRL和OCSP)。
PKI的魅力之一是脱机功能,但如果客户端仅使用CRL来判断证书的有效性,在脱机的情况下就会出现误判,因为当CRL不可用时,大多数客户端都会信任证书,于是攻.击者可以通过切断信道来禁用CRL。谷歌(Google)的亚当•兰利(Adam Langley)曾表示,CRL软故障检查就像一条安全带,只有在发生事故时才起作用。
● CRL的尺寸较大且分布模式复杂,因此它不是一个很好的选择,
● OCSP语义模糊,缺乏历史撤销状态;
● 未解决根证书吊销的问题
● 聚合问题:身份声明(通过标识符进行身份验证)、属性声明(提交一包经过审核的属性)和策略声明组合在一个容器中,这会引发隐私、策略映射和维护问题。
● 委派问题:从技术上讲,CA无法限制下级CA在有限的名称空间或属性集之外颁发证书;X.509的此功能未被使用。因此,互联网上存在大量的CA,对它们进行分类和策略是一项不可完成的任务,一个组织内部的授权不能像一般的商业惯例那样处理。
● 联合身份验证问题:证书链是从属CA、桥接CA和交叉签名的结果,这使得验证复杂且处理时间上昂贵、路径验证语义可能不明确。具有第三方受信任方的层次结构是唯一的模型。如果已经建立了双边信任关系,这将很不方便。
为主机名颁发扩展验证(EV)证书不会阻止颁发对同一主机名较低验证证书的颁发,这意味着较高的EV验证级别无法抵御中间人攻.击。
如果是主体而不是依赖方购买证书,通常会使用最便宜的颁发者,颁发者出于成本考虑,往往采用扩展验证证书来解决问题,但是在安全专家看来,信任价值正在下降。
● 证书颁发机构否认对用户(包括主题或依赖方)的几乎所有保证。
● 有效期应用于限制密钥强度被视为时间足够,此参数被证书颁发机构滥用以向客户端收取扩展费。这给使用密钥滚动的用户带来了不必要的负担。(没看懂啥意思)
●“用户使用未定义的认证请求协议来获取证书,该证书发布于不存在的目录中的不明确位置,从而无有效手段来撤销它。”
与所有企业一样,CA受其经营站点的法律管辖,并可能被迫损害其客户和用户的利益。情报机构还利用了通过CA的法外妥协发出的虚假证书(例如DigiNotar)来进行中间人攻.击。另一个例子是荷兰政府CA的撤销请求,由于新的荷兰法律自2018年1月1日起生效,为荷兰情报和安全部门赋予了新的权力。
X.509实现存在设计缺陷、错误、对标准的不同解释以及不同标准的互操作性问题,一些问题是:
● 许多实现关闭吊销检查:
● 策略被视为障碍,没有得到执行
● 如果默认情况下在所有浏览器(包括代码签名)中都打开了它,可能会破坏基础结构
● DN很复杂且不容易理解(缺乏规范化、国际化问题……)
● RFC822名称有2种表示法
● 几乎不支持名称和策略约束
● keyUsage被忽略,使用列表中的第一个证书
● 自定义oid的实施很困难
● 不应将属性设为强制属性,因为它会使客户端崩溃
● 未指定的属性长度会导致特定于产品的限制
● X.509存在实现错误,例如允许在证书中使用以空值结尾的字符串,或通过代码注入攻.击来伪造使用者名称。
● 通过使用对象标识符的0x80填充子标识符,错误的实现或通过使用客户端浏览器的整数溢出,攻.击者可以在CSR中包含一个未知属性,CA会将其签名,客户端错误地将其解释为“CN”(OID = 2.5.4.3)
数字签名系统依赖于密码散列函数(哈希函数)的安全性。如果公钥基础结构(PKI)使用了不再安全的哈希函数,攻.击者可以利用哈希函数中的弱点来伪造证书。具体来说,如果攻.击者能够实现“哈希碰撞”,他们可以先说服CA用看似无害的内容签名证书,但这些内容的哈希与攻.击者创建的另一组恶意的证书内容的哈希相同,然后,攻.击者可以将CA提供的签名附加到其恶意证书之中,从而生成“似乎由CA签名”的恶意证书。由于恶意证书内容由攻.击者定制,因此它们的有效日期或主机名可能与无害证书不同;恶意证书甚至可以包含“CA:true”字段,从而使其能够颁发其他受信任证书。
● 基于MD2的证书使用了很长时间,容易受到预映像攻.击。由于根证书已经有一个自签名,攻.击者可以使用此签名并将其用于中间证书。
● 2005年,Arjen Lenstra和Benne de Weger演示了“如何使用哈希碰撞“构造两个X.509证书,这两个证书包含相同的签名,并且只在公钥上不同,这是通过对MD5散列函数的碰撞攻.击实现的。
● 2008年,Alexander Sotirov和Marc Stevens在Chaos Communication Congress上提出了一个实用的攻.击,基于RapidSSL仍在发布基于MD5的X.509证书这一事实,他们创建了一个被所有普通浏览器接受的流氓证书颁发机构。
● 2009年4月,在欧洲密码学会议上,麦格理大学(Macquarie University)的澳大利亚研究人员提出了“自动差分路径搜索SHA-1”,研究人员能够推导出一种将碰撞的可能性增加了几个数量级的方法。
● 2017年2月,由Marc Stevens领导的一组研究人员制造了一次SHA-1碰撞,证明了SHA-1的弱点。
利用哈希碰撞来伪造X.509签名的前提是,攻.击者能够预测证书颁发机构将要签名的数据。通过在CA签署的证书中生成一个随机因素(通常是序列号)可以在某种程度上缓解这种情况。自2011年以来,CA /浏览器论坛已在其基准要求第7.1节中要求序列号熵。
所以,序列号是作为一个随机干扰源而存在,它是保密的,在签署证书之前不能对外泄露。
自2016年1月1日起,基线要求禁止使用SHA-1颁发证书。截至2017年初,Chrome 和Firefox拒绝使用SHA-1的证书。截至2017年5月,Edge和Safari都在拒绝SHA-1证书,非浏览器的X.509验证程序尚未拒绝SHA-1证书。
5)PKCS标准概述
在密码学里,PKCS代表“公钥密码学标准”。这是一组由RSA Security Inc.设计和发布的公钥密码标准,始于20世纪90年代初,该公司发布这些标准是为了推广使用他们拥有专利的密码技术,如RSA算法、Schnorr签名算法和其他一些算法。尽管不是行业标准(因为该公司保留了对它们的控制权),但近年来某些标准已经开始进入IETF和PKIX工作组等相关标准化组织的“标准跟踪”过程。
● PKCS#1 2.2 RSA加密标准参见RFC8017。定义了RSA公钥和私钥(以明文编码的ASN.1)的数学属性和格式,以及执行RSA加密、解密和生成及验证签名的基本算法和编码/填充方案。
● PKCS#2-已撤回,从2010年起不再有效,涵盖了RSA对消息摘要的加密,随后合并到PKCS#1中。
● PKCS#3 1.4 Diffie-Hellman密钥协商标准,一种加密协议,它允许彼此不具有先验知识的双方在不安全的通信信道上共同建立共享的秘密密钥。
● PKCS#4-已撤回自2010年起不再有效,涵盖了RSA密钥语法,随后合并到PKCS#1中。
● PKCS#5 2.1基于Password的加密标准,参见RFC 8018和PBKDF2。
● PKCS#6 1.5扩展证书语法标准,定义对旧的v1 X.509证书规范的扩展,被v3淘汰。
● PKCS#7 1.5加密消息语法标准,请参阅RFC2315。用于在PKI下对消息进行签名和/或加密。也用于证书分发(例如作为对PKCS#10消息的响应),形成了S /MIME的基础,S /MIME于2010年基于RFC 5652(一种更新的加密消息语法标准(CMS))建立,通常用于单点登录。
● PKCS#8 1.2私钥信息语法标准,请参见RFC5958。用于携带私钥证书密钥对(加密或未加密)。
● PKCS#9 2.0选定的属性类型[,请参见RFC2985。定义选定的属性类型,以便在PKCS#6扩展证书、PKCS#7数字签名消息、PKCS#8私钥信息和PKCS#10证书签名请求中使用。
● PKCS#10 1.7认证请求标准,请参阅RFC2986。发送给认证机构以请求公钥证书的消息格式,请参阅证书签名请求。
● PKCS#11 2.40密码令牌接口,也称为“ Cryptoki”。定义密码令牌通用接口的API(另请参阅硬件安全模块)。常用于单点登录,公共密钥加密和磁盘加密[10]系统。 RSA Security已将PKCS#11标准的进一步开发移交给了OASIS PKCS 11技术委员会。
● PKCS#12 1.1个人信息交换语法标准,请参阅RFC7292。定义一种文件格式,个人信息交换语法标准[11]见RFC 7292。定义一种文件格式,通常用于存储私钥和附带的公钥证书,并使用基于Password的对称密钥进行保护。PFX是PKCS#12的前身。
此容器格式可以包含多个嵌入式对象,例如多个证书。通常使用密码进行保护/加密。可用作Java密钥存储的格式,并在Mozilla Firefox中建立客户端身份验证证书,可供Apache Tomcat使用。
简单的说,PKCS#12可以包含证书(公钥),也可以包含受密码保护的私钥
● PKCS#13 椭圆曲线密码技术标准(已废弃,唯一的参考是1998年的提案)
● PKCS#14 伪随机数生成(已废弃,没有文档)
● PKCS#15 1.1加密令牌信息格式标准,定义了一个标准,允许加密令牌的用户向应用程序标识自己,而与应用程序的Cryptoki实现(PKCS#11)或其他API无关。RSA放弃了该标准中与IC卡相关的部分,并改为ISO / IEC 7816-15。
本指南演示如何使用OpenSSL命令行工具充当您自己的证书颁发机构(CA)。这在许多情况下都很有用,例如颁发服务器证书以保护intranet网站,或向客户端颁发证书以允许客户端向服务器进行身份验证。
OpenSSL是一个免费的开源加密库,它提供了一些用于处理数字证书的命令行工具,其中一些工具(也就是命令)可以充当证书颁发机构。
证书颁发机构是为数字证书签名的实体。许多网站需要让其客户知道连接是安全的,因此他们向国际证书颁发机构(CA)支付费用,以为其域签署证书。
在某些情况下,自己做自己CA(而不是向DigiCert这样的CA付钱)更有意义,比如保护intranet网站的安全,或向客户端颁发证书以允许客户端向服务器进行身份验证。
充当证书颁发机构意味着要处理密钥对之中的私钥和公钥证书。
我们要创建的第一个密钥对就是根对。这包括根密钥(ca.key.pem)和根证书(ca.cert.pem)。这个“根对”构成了你的CA的身份。
通常,根CA不会直接为服务器或客户端证书签名,根CA仅用于创建一个或多个中间CA,这些中间CA被根CA信任,并代表根CA签署证书,这是最佳实践,它允许根密钥保持脱机状态并尽可能减少使用的次数,因为对根的任何威胁都是灾难性的。
注意:
最佳实践是在安全的环境中创建根对。理想情况下,该计算机应该是完全加密并且空气隔离(含义是没有任何网络接口的机器,即不能通过外部网络连接),可以考虑卸载无线网卡,并用胶水塞满以太网口。
6-2-1)准备目录
mkdir /root/ca 创建目录结构。index.txt和serial文件充当平面文件数据库,以跟踪已签名的证书。 cd /root/ca mkdir certs crl newcerts private chmod 700 private touch index.txt echo 1000 > serial
您必须创建一个配置文件以供OpenSSL使用。
将根CA配置文件从Appendix复制到/root/CA/openssl.cnf,其中的[ca]部分为必填项,这里告诉OpenSSL使用[CA_default]部分中的选项。
[ca] default_ca = CA_default he [CA_default] section contains a range of defaults. Make sure you declare the directory you chose earlier(/root/ca). [CA_default]部分包含一系列默认值,其中的dir字段取值一定要是刚才选择/root/ca: [CA_defalut] #目录和文件位置 dir = /root/ca certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt serial = $dir/serial RANDFILE = $dir/private/.rand # 根密钥和根证书 private_key = $dir/private/ca.key.pem certificate = $dir/certs/ca.cert.pem # 证书吊销列表 crlnumber = $dir/crlnumber crl = $dir/crl/ca.crl.pem crl_extension = crl_ext default_crl_days = 30 # HA-1已弃用,因此请改用SHA-2 defualt_md = sha256 name_opt = ca_default cert_opt = ca_default default_days = 375 preserve = no policy = plicy_strict 我们将对所有根CA签名应用policy_strict,因为根CA仅用于创建中间CA。 [ policy_strict] # 根CA只对匹配的中间证书进行签名 # 请参阅“man ca”的策略格式部分。 countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional 如果值是“ match”,意为请求文件的该字段取值,必须与签署时输入的CA证书的对应字段取值一模一样;如果值是“supplied”,那么它必须存在。如果该值为“optional”,则可选(可留空);所以我们将对所有中间CA签名应用policy_loose而不是policy_strict,因为中间CA正在对可能来自各种第三方的服务器和客户端证书进行签名。 [ policy_loose ] # 允许中间CA签署更多种证书 # 请参见`ca`手册页的“策略格式”部分 countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional 在创建证书或证书签名请求时,将应用[req]部分中的选项。 [ req ] #req”工具的选项(“man req”) default_bits = 2048 distinguished_name = req_distinguished_name string_mask = utf8only # HA-1已弃用,因此请改用SHA-2 default_md = sha256 # 使用-x509选项时要添加的扩展项。 x509_extensions = v3_ca [req_distinguished_name]声明证书签名请求中通常所需的信息,您可以选择指定一些默认值。 [ req_distinguished_name ] # 参看<https://en.wikipedia.org/wiki/Certificate_signing_request>. countryName = Country Name (2 letter code) stateOrProvinceName = State or Province Name localityName = Locality Name 0.organizationName = Organization Name organizationalUnitName = Organizational Unit Name commonName = Common Name emailAddress = Email Address # Optionally, specify some defaults. countryName_default = GB stateOrProvinceName_default = England localityName_default = 0.organizationName_default = Alice Ltd #organizationalUnitName_default = #emailAddress_default = 接下来的几个部分是在签署证书时可以应用的扩展项,例如 -extensions v3_ca命令行参数将应用[v3_ca]中设置的选项。 我们将在创建根证书时应用[v3_ca]扩展: [ v3_ca ] #典型的CA扩展 (`查看x509v3_config手册`). subjectKeyIdentifier = hash autorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true keyUsage = critical, digitalSignature, cRLsign, keyCertSign 我们将在创建中间证书时应用v3_ca_intermediate extension(中间扩展项),pathlen:0保证在中间CA下面不能有其他证书颁发机构: [ v3_intermediate_ca ] # 典型的中间CA的扩展 (`查看x509v3_config手册`). subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign 我们将在签署server_cert(服务器证书,例如用于web服务器的证书)时应用服务器证书扩展: [ server_cert ] # Extensions for server certificates (`查看x509v3_config手册`). basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth 创建证书吊销列表时,将自动应用crl_ext扩展项: [ crl_ext ] # CRL的扩展(`查看x509v3_config手册`). authorityKeyIdentifier=keyid:always 在签署在线证书状态协议(OCSP)证书时,我们将使用ocsp扩展项: [ ocsp ] # OCSP签名证书的扩展项(`man ocsp`). basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
创建根私钥(ca.key.pem)并确保其绝对安全,因为任何拥有根私钥的人都可以颁发“可信证书”,建议使用AES 256算法和复杂的强密码加密根私钥。
注意:出于安全考虑,对所有根CA和中间CA使用4096位私钥。
cd /root/ca openssl genrsa -aes256 -out private/ca.key.pem 4096 Enter pass phrase for ca.key.pem: secretpassword Verifying - Enter pass phrase for ca.key.pem: secretpassword chmod 400 private/ca.key.pem
使用根密钥(ca.key.pem)创建根证书(ca.cert.pem),给根证书一个长的有效期,比如20年。根证书过期后,由根CA签名的所有证书都将无效。
警告:无论何时使用req工具,都必须指定要与-config选项一起使用的配置文件,否则OpenSSL将默认为/etc/pki/tls/OpenSSL.cnf
cd /root/ca openssl req -config openssl.cnf -key private/ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.cert.pem Enter pass phrase for ca.key.pem: secretpassword You are about to be asked to enter information that will be incorporated into your certificate request. ----- Country Name (2 letter code) [XX]:GB State or Province Name []:England Locality Name []: Organization Name []:Alice Ltd Organizational Unit Name []:Alice Ltd Certificate Authority Common Name []:Alice Ltd Root CA Email Address []:
openssl x509 -noout -text -in certs/ca.cert.pem
这行命令的输出包括:
● 使用的签名算法
● 证书生效期
● 公钥位长度
● 颁发者,即签署证书的实体
● 主体,指的是证书本身
由于证书是自签名的,因此颁发者和主题相同。
请注意,所有根证书都是自签名的。
注:以下的黄色汉字是注释,并非证书的组成部分 Signature Algorithm: sha256WithRSAEncryption # 使用的签名算法 Issuer: C=GB, ST=England, O=Alice Ltd, OU=Alice Ltd Certificate Authority, CN=Alice Ltd Root CA # 颁发者 Validity # 证书有效期 Not Before: Apr 11 12:22:58 2015 GMT Not After : Apr 6 12:22:58 2035 GMT Subject: C=GB, ST=England, O=Alice Ltd, OU=Alice Ltd Certificate Authority, CN=Alice Ltd Root CA # 主体 Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (4096 bit) # 公钥位长度
中间证书授权(CA)是可以代表根CA签署证书的实体,根CA签署中间证书,这就形成了信任链。
使用中间证书的目的主要是:根密钥可以保持脱机状态,并尽可能不频繁地使用。如果中间密钥被泄露,根CA可以撤销中间证书并创建新的中间密钥对。
根CA文件保存在/ root / ca中,选择其他目录(/root/ca/intermediate)来存储中间CA文件。
cd /root/ca/intermediate mkdir certs crl csr newcerts private chmod 700 private touch index.txt echo 1000 > serial 将crlnumber文件添加到中间CA目录树,crlnumber用于跟踪证书吊销列表: echo 1000 > /root/ca/intermediate/crlnumber 将中间CA配置文件从Appendix复制到/root/CA/intermediate/openssl.cnf。注意与根CA配置文件相比,以下五个选项变化了: [ CA_default ] dir = /root/ca/intermediate private_key = $dir/private/intermediate.key.pem certificate = $dir/certs/intermediate.cert.pem crl = $dir/crl/intermediate.crl.pem policy = policy_loose
6-3-2) 创建中间密钥
创建中间密钥(intermediate.key.pem),并使用AES 256算法和复杂的强密码将其加密保护。
# cd /root/ca # openssl genrsa -aes256 -out intermediate/private/intermediate.key.pem 4096 Enter pass phrase for intermediate.key.pem: secretpassword Verifying - Enter pass phrase for intermediate.key.pem: secretpassword # chmod 400 intermediate/private/intermediate.key.pem
6-3-3) 创建中间证书
使用中间证书创建证书签名请求(CSR),详细信息通常应与根CA相同。但 Common Name(证书持有者通用名/FQDN)必须不同:
警告:请确保命令行指定的中间 CA 配置文件存在(intermediate/openssl.cnf)。
# cd /root/ca # openssl req -config intermediate/openssl.cnf -new -sha256 -key intermediate/private/intermediate.key.pem -out intermediate/csr/intermediate.csr.pem Enter pass phrase for intermediate.key.pem: secretpassword You are about to be asked to enter information that will be incorporated into your certificate request. ----- Country Name (2 letter code) [XX]:GB State or Province Name []:England Locality Name []: Organization Name []:Alice Ltd Organizational Unit Name []:Alice Ltd Certificate Authority Common Name []:Alice Ltd Intermediate CA Email Address []:
要创建中间证书,请使用带有v3_intermediate_CA扩展项的根CA对中间CSR进行签名。中间证书的有效期应短于根证书。十年是合理的。
警告:指定根CA配置文件 /root/ca/openssl.cnf。
# cd /root/ca # openssl ca -config openssl.cnf -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem Enter pass phrase for ca.key.pem: secretpassword Sign the certificate? [y/n]: y # chmod 444 intermediate/certs/intermediate.cert.pem index.txt文件是OpenSSL CA工具存储证书数据库的位置,请勿手动删除或编辑此文件。现在它应该包含刚才创建的中间证书: V 250408122707Z 1000 unknown ... /CN=Alice Ltd Intermediate CA
6-3-4) 验证中间证书
正如我们对根证书所做的那样,请检查中间证书的详细信息是否正确:
# openssl x509 -noout -text -in intermediate/certs/intermediate.cert.pem
intermediate.cert.pem: OK
当应用程序(如web浏览器)尝试验证由中间CA签名的证书时,它必须对照根证书验证中间证书。要完成信任链,请创建CA证书链以呈现给应用程序。
要创建CA证书链,请将中间证书和根证书连接在一起,我们稍后将使用此文件来验证由中间CA签名的证书。
# cat intermediate/certs/intermediate.cert.pem certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem # chmod 444 intermediate/certs/ca-chain.cert.pem
注意:证书链文件必须包含根证书,因为需要让客户端应用程序找到它。更好的选择(尤其是在管理Intranet的情况下)是在需要连接的每个客户端上安装根证书,在这种情况下,证书链文件仅需要包含您的中间证书。
我们将使用中间 CA 签署证书。您可以在各种情况下使用这些证书,例如保护与 Web 服务器的连接或对连接到服务器的客户端进行身份验证。
注意:以下步骤是CA替申请者创建私钥和签名请求(CSR),但申请者从安全角度考虑也可以自己创建私钥和请求,其中的私钥妥善保存于本地,把CSR交给CA,CA则还给它一个签名的证书。在这种情况下,跳过 genrsa 和 req 命令。
我们的根密钥对和中间密钥对是4096位,服务器证书和客户端证书通常在一年后过期,因此我们可以安全地使用2048位。
注意:尽管4096位比2048位更安全,但它会减慢TLS握手速度并显着增加握手期间的处理器负载。因此,大多数网站使用2048位的密钥对。
译者注:2048位已经不再安全,建议使用4096或8192位。
如果要创建用于网络服务器的密钥对,每次重启该服务器时都需要输保护密码,如果嫌麻烦可以不使用-aes256选项以创建没有密码的私钥。
# cd /root/ca # openssl genrsa -aes256 -out intermediate/private/www.example.com.key.pem 2048 # chmod 400 intermediate/private/www.example.com.key.pem
6-4-2) 创建证书
使用私钥创建证书签名请求(CSR),并且CSR的详细信息无需与中间CA相匹配。对于服务器证书,Common Name(公用名)必须是FQDN(完全限定的域名,例如,www.example.com),而对于客户端证书,Common Name可以是任何唯一标识符(例如电子邮件地址),请注意,客户端证书的Common Name与根证书或中间证书的Common Name不同。
# cd /root/ca #openssl req -config intermediate/openssl.cnf -key intermediate/private/www.example.com.key.pem -new -sha256 -out intermediate/csr/www.example.com.csr.pem Enter pass phrase for www.example.com.key.pem: secretpassword You are about to be asked to enter information that will be incorporated into your certificate request. ----- Country Name (2 letter code) [XX]:US State or Province Name []:California Locality Name []:Mountain View Organization Name []:Alice Ltd Organizational Unit Name []:Alice Ltd Web Services Common Name []:www.example.com Email Address []:
要创建证书,请使用中间CA对CSR进行签名。如果要在服务器上使用证书,请使用 server_cert扩展项;如果证书将用于用户身份验证,请使用usr_cert扩展项。证书的有效期通常为一年,不过为了方便起见,CA通常会多给几天时间。
# cd /root/ca #openssl ca -config intermediate/openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in intermediate/csr/www.example.com.csr.pem -out intermediate/certs/www.example.com.cert.pem # chmod 444 intermediate/certs/www.example.com.cert.pem intermediate/index.txt应该出现包含该证书的行: V 160420124233Z 1000 unknown ... /CN=www.example.com
6-4-3) 验证证书
# openssl x509 -noout -text -in intermediate/certs/www.example.com.cert.pem
Issuer(颁发者)是中间CA,Subject(主题)是指证书本身: Signature Algorithm: sha256WithRSAEncryption Issuer: C=GB, ST=England,O=Alice Ltd, OU=Alice Ltd Certificate Authority,CN=Alice Ltd Intermediate CA Validity Not Before: Apr 11 12:42:33 2015 GMT Not After : Apr 20 12:42:33 2016 GMT Subject: C=US, ST=California, L=Mountain View,O=Alice Ltd, OU=Alice Ltd Web Services,CN=www.example.com Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) 输出还将显示X509v3扩展。创建证书时,您使用了server_cert或usr_cert扩展项,相应配置部分中的选项将反映在输出中: X509v3 extensions: X509v3 Basic Constraints: CA:FALSE Netscape Cert Type: SSL Server Netscape Comment: OpenSSL Generated Server Certificate X509v3 Subject Key Identifier: B1:B8:88:48:64:B7:45:52:21:CC:35:37:9E:24:50:EE:AD:58:02:B5 X509v3 Authority Key Identifier: keyid:69:E8:EC:54:7F:25:23:60:E5:B6:E7:72:61:F1:D4:B9:21:D4:45:E9 DirName:/C=GB/ST=England/O=Alice Ltd/OU=Alice Ltd Certificate Authority/CN=Alice Ltd Root CA serial:10:00 X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication 使用我们先前创建的CA证书链文件(ca-chain.cert.pem)来验证新证书是否具有有效的信任链。 # openssl verify -CAfile intermediate/certs/ca-chain.cert.pem intermediate/certs/www.example.com.cert.pem www.example.com.cert.pem: OK
6-4-4) 部署证书
现在,您可以将新证书部署到服务器,也可以将证书分发给客户端。部署到服务器应用程序(例如Apache)时,确保以下文件可用:
ca-chain.cert.com
www.example.com.key.pem
www.example.com.cert.pem
如果您是从第三方获得CSR,那就无需使用它的私钥,因此只需将证书链文件(ca-chain.cert.pem)和证书(www.example.com.cert.pem)发回给它们。
证书吊销列表 (CRL,见RFC5280) 提供已吊销的证书的列表。客户端应用程序(如 Web 浏览器)可以使用 CRL 检查服务器的真实性。服务器应用程序(如Apache或OpenV.P.N)可以使用 CRL 拒绝访问不再受信任的客户端。
在公共可访问的位置(例如http://example.com/intermediate.crl.pem)发布 CRL,第三方可以从此位置获取 CRL,以检查他们依赖的证书是否已被吊销。
注意:一些应用程序供应商已弃用CRL,而是使用联机证书状态协议(OCSP,百度RFC2560,有中文版)。
证书颁发机构在签署证书时,通常会将CRL位置编码到证书中,将crlDistributionPoints添加到适当的部分,对于本例,将其添加到[server_cert]部分。
[ server_cert ]
# ... snipped ...
crlDistributionPoints = URI:http://example.com/intermediate.crl.pem
# cd /root/ca
# openssl ca -config intermediate/openssl.cnf -gencrl -out intermediate/crl/intermediate.crl.pem
注意:ca手册页的CRL OPTIONS部分包含有关如何创建CRL的更多信息。
您可以使用 crl 工具检查 CRL 的内容:
openssl crl -in intermediate/crl/intermediate.crl.pem -noout -text
尚未吊销任何证书,因此输出将显示“无吊销证书”
您应该定期重新创建CRL。默认情况下,CRL在30天后过期。这由[CA_default]部分的default_crl_days选项控制。
让我们看一个例子。爱丽丝(Alice)正在运行Apache服务器,并有一个私人文件夹,上面放着可爱的小猫图片。 爱丽丝想授予她的朋友鲍勃(Bob)访问此收藏的权限。
①Bob创建一个私钥和证书签名请求(CSR):
cd /home/bob openssl genrsa -out bob@example.com.key.pem 2048 openssl req -new -key bob@example.com.key.pem -out bob@example.com.csr.pem You are about to be asked to enter information that will be incorporated into your certificate request. ----- Country Name [XX]:US State or Province Name []:California Locality Name []:San Francisco Organization Name []:Bob Ltd Organizational Unit Name []: Common Name []:bob@example.com Email Address []:
②Bob将自己的CSR发送给爱丽丝,爱丽丝随后对其进行签名:
cd /root/ca openssl ca -config intermediate/openssl.cnf -extension usr_cert -notext -md sha256 -in intermediate/csr/bob@example.com.csr.pem -out intermediate/certs/bob@example.com.cert.pem
③Alice 验证证书是否有效:
openssl verify -CAfile intermediate/certs/ca-chain.cert.pem intermediate/certs/bob@example.com.cert.pem bob@example.com.cert.pem: OK
现在index.txt文件应包含一个新条目:
V 160420124740Z 1001 unknown ... /CN=bob@example.com
Alice向Bob发送签名证书,Bob将证书安装在自己的网络浏览器中,现在可以访问爱丽丝的小猫图片,欢呼吧!
④但可悲的是,事实证明Bob行为不端,Bob将Alice的小猫图片发布到了《***新闻》上,声称是他自己的照片并广受欢迎,爱丽丝发现了,需要立即撤销了他的访问权限:
cd /root/ca openssl ca -config intermediate/openssl.cnf -revoke intermediate/certs/bob@example.com.cert.pem Enter pass phrase for intermediate.key.pem: secretpassword Revoking Certificate 1001. Data Base Updated
现在index.txt中与Bob的证书相对应的行以字符R开头,这表示证书已被吊销:
R 160420124740Z 150411125310Z 1001 unknown ... /CN=bob@example.com
撤销Bob的证书后,Alice必须重新创建CRL。
6-5-4) 服务器端使用CRL
对于客户端证书,通常是服务器端应用程序(如Apache)进行验证。此应用程序需要具有对CRL的本地访问权限。
对于Alice,她可以将SSLCARevocationPath指令添加到Apache配置中,然后将CRL复制到她的Web服务器上,下次Bob连接到Web服务器时,Apache将根据CRL检查其客户端证书并拒绝访问。
同样,OpenV.P.N具有crl-verfiy指令,因此它可以阻止证书被吊销的客户端。
对于服务器证书,通常是服务器端应用程序(如web浏览器)(译者注:不知是否是英文原文的笔误,Web浏览器应该是客户端程序)进行验证。此应用程序必须具有对CRL的删除访问权限。
如果使用包含crlDistributionPoints的扩展项签署了证书,则客户端应用程序可以读取此信息并从指定位置获取CRL。
CRL分发点在证书X509v3详细信息中可见。
opnessl x509 -in cute-kitten-pictures.example.com.cert.pem -noout -text X509v3 CRL Distribution Points: Full Name: URI:http://example.com/intermediate.crl.pem
6-6) 在线证书状态协议OCSP
百度RFC2560,有中文版。
联机证书状态协议(OCSP)是证书吊销列表(CRL)的替代方案。与CRL类似,OCSP允许请求方(如web浏览器)确定证书的吊销状态。
当CA签署证书时,它们通常会在证书中包含OCSP服务器地址。这在功能上与用于CRL的crlDistributionPoints相似。
例如,当服务器向web浏览器提供了证书,浏览器将向证书中指定的OCSP服务器地址发送查询,OCSP响应者在此地址侦听查询,并以证书的吊销状态做出响应。
注:建议在可能的情况下使用OCSP,实际上您只需要OCSP来获得网站证书,因为一些web浏览器已不再支持CRL。
要使用OCSP,CA必须将OCSP服务器位置编码到它所签署的证书中。在适当的部分中使用authorityInfoAccess选项,在本例中指的是[ server_cert ]部分。
[ server_cert ]
# ... snipped ...
authorityInfoAccess = OCSP;URI:http://ocsp.example.com
OCSP响应程序需要一个密钥对,用来对发回给请求方的响应进行签名。OCSP密钥对必须由当前正在检查的证书的同一CA签署。
创建私钥并使用 AES-256 对其进行加密保护:
# cd /root/ca # openssl genrsa -aes256 -out intermediate/private/ocsp.example.com.key.pem 4096
创建证书签名请求(CSR),详细信息通常应与签名CA的详细信息匹配。但是,公用名必须是完全限定的域名:
# cd /root/ca # openssl req -config intermediate/openssl.cnf -new -sha256 -key intermediate/private/ocsp.example.com.key.pem -out intermediate/csr/ocsp.example.com.csr.pem Enter pass phrase for intermediate.key.pem: secretpassword You are about to be asked to enter information that will be incorporated into your certificate request. ----- Country Name (2 letter code) [XX]:GB State or Province Name []:England Locality Name []: Organization Name []:Alice Ltd Organizational Unit Name []:Alice Ltd Certificate Authority Common Name []:ocsp.example.com Email Address []: 使用中间 CA 签署 CSR: # openssl ca -config intermediate/openssl.cnf -extensions ocsp -days 375 -notext -md sha256 -in intermediate/csr/ocsp.example.com.csr.pem -out intermediate/certs/ocsp.example.com.cert.pem 验证证书具有正确的X509v3扩展: # openssl x509 -noout -text \ -in intermediate/certs/ocsp.example.com.cert.pem X509v3 Key Usage: critical Digital Signature X509v3 Extended Key Usage: critical OCSP Signing
6-6-3) 吊销证书
OpenSSL ocsp工具可以充当OCSP响应程序,但仅用于测试。存在可用于生产的OCSP响应程序,但是这些响应程序不在本指南的范围内。
创建要测试的服务器证书:
# cd /root/ca # openssl genrsa -out intermediate/private/test.example.com.key.pem 2048 # openssl req -config intermediate/openssl.cnf -key intermediate/private/test.example.com.key.pem -new -sha256 -out intermediate/csr/test.example.com.csr.pem # openssl ca -config intermediate/openssl.cnf -extensions server_cert -days 375 -notext -md sha256 -in intermediate/csr/test.example.com.csr.pem -out intermediate/certs/test.example.com.cert.pem
在本地主机上运行OCSP响应程序。OCSP响应程序不会将吊销状态存储在单独的CRL文件中,而是直接读取index.txt。响应使用OCSP私钥对签名(使用-rkey和-rsigner选项):
openssl ocsp -port 127.0.0.1:2560 -text -sha256 -index intermediate/index.txt -CA intermediate/certs/ca-chain.cert.pem -rkey intermediate/private/ocsp.example.com.key.pem -rsigner intermediate/certs/ocsp.example.com.cert.pem -nrequest 1
另一个终端向OCSP响应程序发送查询。-cert选项指定要查询的证书:
# openssl ocsp -CAfile intermediate/certs/ca-chain.cert.pem -url http://127.0.0.1:2560 -resp_text -issuer intermediate/certs/intermediate.cert.pem -cert intermediate/certs/test.example.com.cert.pem
输出的开头显示:
● 是否收到成功响应(OCSP 响应状态:OCSP Response Status)
● 然后是响应者的身份(应答器 ID:Responder Id)
● 证书的吊销状态(证书状态:Cert Status)
OCSP Response Data: OCSP Response Status: successful (0x0) Response Type: Basic OCSP Response Version: 1 (0x0) Responder Id: ... CN = ocsp.example.com Produced At: Apr 11 12:59:51 2015 GMT Responses: Certificate ID: Hash Algorithm: sha1 Issuer Name Hash: E35979B6D0A973EBE8AEDED75D8C27D67D2A0334 Issuer Key Hash: 69E8EC547F252360E5B6E77261F1D4B921D445E9 Serial Number: 1003 Cert Status: good This Update: Apr 11 12:59:51 2015 GMT
吊销证书:
# openssl ca -config intermediate/openssl.cnf -revoke intermediate/certs/test.example.com.cert.pem Enter pass phrase for intermediate.key.pem: secretpassword Revoking Certificate 1003. Data Base Updated
如前所述,本机运行OCSP响应程序,另一个终端发送查询。这次的输出显示的证书状态已经改变:已吊销和吊销时间:
OCSP Response Data: OCSP Response Status: successful (0x0) Response Type: Basic OCSP Response Version: 1 (0x0) Responder Id: ... CN = ocsp.example.com Produced At: Apr 11 13:03:00 2015 GMT Responses: Certificate ID: Hash Algorithm: sha1 Issuer Name Hash: E35979B6D0A973EBE8AEDED75D8C27D67D2A0334 Issuer Key Hash: 69E8EC547F252360E5B6E77261F1D4B921D445E9 Serial Number: 1003 Cert Status: revoked Revocation Time: Apr 11 13:01:09 2015 GMT This Update: Apr 11 13:03:00 2015 GMT
6-7) 附录
# OpenSSL root CA 配置文件。 # Copy to `/root/ca/openssl.cnf`. [ ca ] # `man ca` default_ca = CA_default [ CA_default ] # 目录和文件位置。 dir = /root/ca certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt serial = $dir/serial RANDFILE = $dir/private/.rand # 根私钥和根证书。 private_key = $dir/private/ca.key.pem certificate = $dir/certs/ca.cert.pem # 用于证书吊销列表。 crlnumber = $dir/crlnumber crl = $dir/crl/ca.crl.pem crl_extensions = crl_ext default_crl_days = 30 # 不推荐使用SHA-1,因此请改用SHA-2。 default_md = sha256 name_opt = ca_default cert_opt = ca_default default_days = 375 preserve = no policy = policy_strict [ policy_strict ] # 根CA只对match(匹配)的中间证书进行签名。 # 请参阅`man ca`的POLICY FORMAT部分。 countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional [ policy_loose ] # 允许中间CA签署更多种类的证书。 # 请参阅“ca”手册页的“策略格式”部分。 countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] # `req` 工具选项 (`man req`). default_bits = 2048 distinguished_name = req_distinguished_name string_mask = utf8only # 不推荐使用SHA-1,请改用SHA-2。 default_md = sha256 # 使用 -x509选项时要添加的扩展项。 x509_extensions = v3_ca [ req_distinguished_name ] # See <https://en.wikipedia.org/wiki/Certificate_signing_request>. countryName = Country Name (2 letter code) stateOrProvinceName = State or Province Name localityName = Locality Name 0.organizationName = Organization Name organizationalUnitName = Organizational Unit Name commonName = Common Name emailAddress = Email Address #指定一些默认值(可选)。 countryName_default = GB stateOrProvinceName_default = England localityName_default = 0.organizationName_default = Alice Ltd organizationalUnitName_default = emailAddress_default = [ v3_ca ] # 典型CA的扩展(`man x509v3_config`)。 subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ v3_intermediate_ca ] #典型中间CA的扩展(`man x509v3_config`)。 subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ usr_cert ] # 客户端证书的扩展项(`man x509v3_config`)。 basicConstraints = CA:FALSE nsCertType = client, email nsComment = "OpenSSL Generated Client Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, emailProtection [ server_cert ] # 服务器证书的扩展项 (`man x509v3_config`). basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ crl_ext ] # CRL扩展项(`man x509v3_config`). authorityKeyIdentifier=keyid:always [ ocsp ] # OCSP签名证书的扩展项 (`man ocsp`). basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
# OpenSSL中间CA配置文件。 # Copy to `/root/ca/intermediate/openssl.cnf`. [ ca ] # `man ca` default_ca = CA_default [ CA_default ] # 目录和文件位置。 dir = /root/ca/intermediate certs = $dir/certs crl_dir = $dir/crl new_certs_dir = $dir/newcerts database = $dir/index.txt serial = $dir/serial RANDFILE = $dir/private/.rand # 根私钥和根证书。 private_key = $dir/private/intermediate.key.pem certificate = $dir/certs/intermediate.cert.pem # 用于证书吊销列表。 crlnumber = $dir/crlnumber crl = $dir/crl/intermediate.crl.pem crl_extensions = crl_ext default_crl_days = 30 # 不推荐使用SHA-1,请改用SHA-2。 default_md = sha256 name_opt = ca_default cert_opt = ca_default default_days = 375 preserve = no policy = policy_loose [ policy_strict ] # 根CA只对match(匹配)的中间证书进行签名。 # 请参阅`man ca`的POLICY FORMAT部分。 countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional [ policy_loose ] # 允许中间CA签署更多种类的证书。 # 请参阅“ca”手册页的“策略格式”部分。 countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ req ] # `req` 工具选项 (`man req`)。 default_bits = 2048 distinguished_name = req_distinguished_name string_mask = utf8only # 不推荐使用SHA-1,请改用SHA-2。 default_md = sha256 # 使用 -x509选项时要添加的扩展项。 x509_extensions = v3_ca [ req_distinguished_name ] # See <https://en.wikipedia.org/wiki/Certificate_signing_request>. countryName = Country Name (2 letter code) stateOrProvinceName = State or Province Name localityName = Locality Name 0.organizationName = Organization Name organizationalUnitName = Organizational Unit Name commonName = Common Name emailAddress = Email Address # 指定一些默认值(可选)。 countryName_default = GB stateOrProvinceName_default = England localityName_default = 0.organizationName_default = Alice Ltd organizationalUnitName_default = emailAddress_default = [ v3_ca ] # 典型CA的扩展(`man x509v3_config`)。 subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ v3_intermediate_ca ] #典型中间CA的扩展(`man x509v3_config`)。 subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign [ usr_cert ] # 客户端证书的扩展项(`man x509v3_config`)。 basicConstraints = CA:FALSE nsCertType = client, email nsComment = "OpenSSL Generated Client Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, emailProtection [ server_cert ] # 服务器证书的扩展项 (`man x509v3_config`)。 basicConstraints = CA:FALSE nsCertType = server nsComment = "OpenSSL Generated Server Certificate" subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer:always keyUsage = critical, digitalSignature, keyEncipherment extendedKeyUsage = serverAuth [ crl_ext ] # CRL扩展项(`man x509v3_config`)。 authorityKeyIdentifier=keyid:always [ ocsp ] # OCSP签名证书的扩展项 (`man ocsp`) basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer keyUsage = critical, digitalSignature extendedKeyUsage = critical, OCSPSigning
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。