OpenSSL 的结构
?
OpenSSL 官网:https://www.openssl.org/
X.509 标准来自国际电信联盟电信标准(ITU-T)的 X.500 标准。
X.509 标准是国际互联网工程任务组(IETF)的 PKIX 小组用来建设互联网的 PKI 公钥基础设施的标准。
HTTPS 中使用 X.509 的 PKI 标准。
X.509 标准目前最通用的版本为 X.509 V3 版本,引入了证书扩展的概念。
X.509 标准主要内容:证书的作用、证书文件的结构、证书管理方式、证书校验方式、证书的撤销等。
ASN.1是国际电信联盟电信标准(ITU-T)定义的标准,用来结构化描述证书。
ASN.1是一种抽象的数据结构,描述了复杂的对象,以及对象之间的关系。
💡💡💡
X.509 标准定义了证书应该包含的内容,而为了让机器和人更好地理解和组织 X.509 标准,可以采用 ASN.1标准来描述 X.509 标准(或者说证书),ASN.1 类似于伪代码,是一种可理解的数据结构。
-
为了方便证书在互联网中传输,需要通过一个规则将 ASN.1转换为二进制文件。在 X.509 中,使用的编码方式是 Distinguished Encoding Rules(DER)。ASN.1和 DER 的关系类似于字符集和编码的关系。
-
Basic Encoding Rules(BER)是 DER 的一个子集。
-
Canonical Encoding Rules(CER)是另外一种编码标准,用来编码 ASN.1 结构。
-
DER 是一个二进制文件,为了方便传输,可以将 DER 转换为 PEM(Privacy-enhanced Electronic Mail)格式,PEM 是 base64 编码方式。
参考:
- 在线 Web 工具:SSL Converter - 转换证书的各种格式
- 阿里云文档:主流字证书都有哪些格式?
使用 x509 子命令进行 PEM 和 DER 证书文件之间的格式转换:
参数:
- -in,输入文件。
- -out,输出文件。
- -inform,输入文件的原有编码方式。
- -outform,输出文件编码方式。
PKCS#12 格式可以将证书和密钥对打包成一个文件,还可以对文件进行加密保护。
PKCS#12 文件后缀一般是 .pkcs12、.pfx、.p12。
通过 OpenSSL pkcs12 子命令将密钥对(privkey.pem)、服务器实体证书(cert.pem)、中间证书(chain.pem)转换成一个文件,并使用口令进行保护:
当需要使用证书时,可以从 cert.pfx 导出密钥对和证书,需要输入口令:
PKCS#7 格式主要用来进行数字签名和数据加密。
PKCS#7 文件后缀一般是 .p7b 或 .p7c。
使用 crl2pkcs7 子命令生成 cert.p7b 文件:
参数:
- -certfile 表示服务器证书。
- 另一个 -certfile 表示中间件证书,不包含根证书。
- -nocrl 表示不加载证书对应的 CRL 文件。
从 cert.p7b 文件中导出服务器证书文件和中间件证书文件:
openssl 是目前最流行的 SSL 密码库工具,其提供了一个通用、健壮、功能完备的工具套件,用以支持SSL/TLS 协议的实现。
以下为测试正式生成过程而做的实验,基本模拟了整个证书的生成过程。
生成服务器端私钥
命令:
// 生成服务器端公钥
命令:
// 生成 CA 私钥
命令:
命令:
//会出来一个填写资料的界面,Common Name这一项,是最后可以访问的域名
命令:
// 服务器端需要向 CA 机构申请签名证书,在申请签名证书之前依然是创建自己的 CSR 文件
命令:
// 向自己的 CA 机构申请证书,签名过程需要 CA 的证书和私钥参与,最终颁发一个带有 CA 签名的证书
命令:
同样会有信息填写,照旧写就好了
//使用openssl 进行转换
命令:
如果完成,就会得到这么9个文件
证书链可以有任意环节的长度,所以在三节的链中,信任锚证书CA 环节可以对中间证书签名;中间证书的所有者可以用自己的私钥对另一个证书签名。CertPath API 可以用来遍历证书链以验证有效性,也可以用来构造这些信任链。
Web 浏览器已预先配置了一组浏览器自动信任的根 CA 证书。来自其他证书授权机构的所有证书都必须附带证书链,以检验这些证书的有效性。证书链是由一系列 CA 证书发出的证书序列,最终以根 CA 证书结束。
我们一般会有三种证书:
- RootCA.crt(rCA,被信任的根证书)、
- IntermediateCA.crt(mCA,某些厂商有多个中间证书)、
- server.crt(sCA,通过CSR签下来的证书)
为了让浏览器能够信任我们的证书,我们需要配置一条完整的证书链,证书链由sCA和mCA构成就好,rCA是浏览器内置,不需要服务器给提供。
nginx配置证书链的时候,就是指定一个证书文件,这个文件中含有我们整个证书链的所有证书就好。
证书合并的时候,正确的合并方法是把 mCA 合并到 sCA 中。当有多个 mCA 文件时,mCA 从下级到上级(根证书为最上级)依次合并到 sCA 中。
?
证书链的使用与*.pem证书中-----BEGIN CERTIFICATE-----的证书顺序有关。
有两条证书链:a->b->c->d? 和? a->b->e->f
证书链默认使用:a->b->c->d
?
如果证书配置如下:
证书链默认使用:a->b->e->f
?
使用 OpenSSL 获取服务器实体证书、中间证书、根证书。
在线 Web 工具:SSL Certificate Checker - 分析网站证书的工具,可以在线下载证书及证书链
openssl s_client -connect www.github.com:443 -showcerts
openssl s_client -connect www.github.com:443 -showcerts
输出内容如下:
使用 Shell 命令提取证书链中的服务器实体证书和中间证书:
完整的证书链文件保存在 www_fullchain.pem 文件中,然后将 www_fullchain.pem 拆分成各个文件:
? 注:这里拆分文件存在命令行语法错误,待解决。
首先,找到证书链中最底部的一张证书(即根证书签发的第一张中间证书),然后通过证书中包含的 CA Issures 信息获取上一级证书(即根证书)的地址。
如何更新系统的根证书?
使用 Mozilla 根证书库创建可信证书库的两种方式:
-
从 Mozilla CA Certificate Store 获取开源的可信证书库:Source file with all of the included root certificates。下载完成后,可以使用 Perl 脚本或者 Go 脚本将 certdata.txt 文件转换为 PEM 格式。
-
使用 Curl 获取最新的 PEM 格式的可信证书库:CA certificates extracted from Mozilla。
在 Linux 系统中,可以使用 Mozilla 根证书库更新系统的根证书库。
-
下载 Mozilla 根证书库。
CA 机构的根证书文件存放在 /usr/share/ca-certificates/mozilla 目录下。
同时 /etc/ca-certificates.conf 文件也会更新,该文件包含了 Mozilla 各个根证书文件的列表。
-
使用 update-ca-certificates 工具将 Mozilla 的各个根证书文件同步到系统的根证书库中。
update—certificates 工具会读取 /etc/ca-certificates.conf 文件,找到所有 Mozilla 配置的根证书文件,然后将 /usr/share-certificates/mozilla 下的根证书文件复制到 /etc/ssl/certs 目录下,同时 /etc/ssl/certs-certificates.crt 文件也会更新,该文件比较大,包含了所有的根证书文件,相当于所有根证书文件的集合。
-
将自签名证书同步到系统根证书库中。
服务器实体为了证明自己的身份,需要向 CA 机构申请证书。
在申请证书之前,必须先生成一个 CSR 文件,CSR 文件是要求 CA 给证书签名的一种正式申请,该文件中包含申请证书的实体的公钥以及该实体的相关信息。然后再将 CSR 文件发送给 CA 机构。
CSR 文件标准:PKCS#10 标准。
推荐阅读:花生壳:SSL 证书请求文件 (CSR) 生成指南
使用 OpenSSL req 子命令,通过非交互式方式同时生成密钥对和 CSR 文件,命令如下:
参数:
- -sha256 表示证书使用 sha256 算法生成摘要(Hash 值)然后计算签名。
- -newkey 表示生成一个 2048 比特的 RSA 密钥对文件。
- -subj 参数表示手动设置 CSR 请求信息,不用进行交互式输入。
- -keyout 表示输出密钥对文件。
- -out 表示输出 CSR 文件。
更新一张证书,并且不想对里面的信息作任何更改:
使用 OpenSSL req 子命令查看 CSR 文件内容:
输出 CSR 文件示例:
在线 Web 工具:CSR Decoder - 解析 CSR 文件的一个小工具
CA 会使用服务器实体的公钥验证 CSR 文件的签名,确保 CSR 文件没有被篡改。
请勿在生产环境中使用自签名证书,自签名证书的唯一目的是测试。
使用 OpenSSL 管理密钥和证书的步骤:
image
- 通常情况下,使用 2048 位的 RSA 算法,因为 DSA 算法因效率问题会被限制在 1024 位,而 ECDSA 算法则还没有被大部分 CA/客户端支持。
如何生成自签名证书:
自签名证书生成步骤
执行以下 OpenSSL 命令生成自签名证书:
注:了解 RSA 算法的更多实践,参考之前写的博客:密码学—密码算法与协议
使用 OpenSSL x509 子命令生成自签名证书:
参数:
- -days 参数表示证书的有效期。
- -in 表示 CSR 文件。
- -signkey 表示密钥对的公钥。
- -out 表示输出的证书文件。
- -extfile 表示引用一个扩展文件。
数字证书基本格式见文章末尾。
?
参数:
-
-in 表示要查看的证书文件。
-
-text 表示打印详细信息。
-
-noout 表示不打印编码后的证书内容,以减少信息干扰。
下载 CRLs 文件,手动查看服务器实体证书的序列号是否存在于 CRLs 中,如果存在说明证书被吊销了,这种方式不校验 CRLs 的签名。
Let’ s Encrypt 认为 CRL 的作用已经不大,所以其签发的证书并不包含CRL分发点信息。
查看 CRLS 文件内容:
通过 OpenSSL verify 子命令自动校验证书的吊销状态:
Let‘s Encrypt 的 OCSP 响应不包含 Certificate 信息,而 GeoTrust 的 OCSP 响应包含 Certificate 信息:
以上方法实测存在问题。
OCSP 封套相比标准 OCSP 来说,不是由浏览器发出 OCSP 请求,而是由证书部署者即服务器负责发出 OCSP 请求。
说明,并不是所有的 HTTPS 网站都支持 OCSP 封套。
?
输出内容如下:
通过证书透明度机制,CA 机构、服务器实体、客户端能够监控、审计证书的签发、使用,确保证书是被正确使用的。
查看 github 的 SCT:
在线查看支持 OCSP 封套的网站:
如何保证基础结构的安全?
- 根密钥必须离线保存。
- CRL 和 OSCP 响应程序证书必须定期进行更新,而这会要求根密钥保持联机。
创建全新 CA 的步骤:
- 根 CA 配置;
- 创建根 CA 的目录结构和初始化密钥文件;
- 生成根 CA 的密钥和证书;
RFC 3280 规定了 X.509 数字证书的基本格式
?