OpenSSL 概述

OpenSSL 的结构

OpenSSL 目录功能对照表

目录名功能描述
Crypto存放 OpenSSL 所有加密算法源码文件和相关标注如 X.509 源码文件,是 OpenSSL 中最重要的目录,包含了 OpenSSL 密码算法库的所有内容
SSL存放 OpenSSL 中 SSL 协议各个版本和 TLS 1.0 协议源码文件,包含了 OpenSSL 协议库的所有内容
Apps存放 OpenSSL 中所有应用程序源码文件,如 CA、X509 等应用程序的源文件就存放在这里
Doc存放了 OpenSSL 中所有的使用说明文档,包含三个部分:应用程序说明文档、加密算法库 API 说明文档及 SSL 协议API说明文档
Demos存放了一些基于 OpenSSL 的应用程序例子,这些例子一般都很简单,演示怎么使用 OpenSSL 中的一个功能
Include存放了使用 OpenSSL 的库时需要的头文件
Test存放了 OpenSSL 自身功能测试程序的源码文件

查看 OpenSSL 版本

# 查看当前系统使用的 OpenSSL 版本$ openssl versionOpenSSL 1.0.2g  1 Mar 2016# 获取完整的版本信息$ openssl version -a ...OPENSSLDIR: "/usr/lib/ssl" # OpenSSL 默认查找和配置证书目录

构建特定版本的 OpenSSL

OpenSSL 官网:https://www.openssl.org/

# 下载 OpenSSL 二进制包$ wget https://www.openssl.org/source/openssl-1.1.1.tar.gz# 解压缩,先调用 gzip 解压缩,再解开文件。$ tar -xzvf openssl-1.0.2o.tar.gz # 安装配置$ cd openssl-1.0.2o/$ ./config \--prefix=/opt/openssl \--openssldir=/opt/openssl \ # 设置安装目录enable-ec_nistp_64_gcc_128  # 使用优化后的常用椭圆曲线算法$ make depend       # 生成可执行文件$ make              # 编译$ sudo make install # 安装# OpenSSL 安装在 /opt/openssl/ 目录下$ cd /opt/openssl/$ ls -ltotal 40drwxr-xr-x 2 root root  4096 Jun 15 08:08 bindrwxr-xr-x 2 root root  4096 Jun 15 08:08 certs   # 根证书目录、可信证书库drwxr-xr-x 3 root root  4096 Jun 15 08:08 includedrwxr-xr-x 4 root root  4096 Jun 15 08:08 libdrwxr-xr-x 6 root root  4096 Jun 15 08:08 mandrwxr-xr-x 2 root root  4096 Jun 15 08:08 misc    # 补充脚本-rw-r--r-- 1 root root 10835 Jun 15 08:08 openssl.cnfdrwxr-xr-x 2 root root  4096 Jun 15 08:08 private # 私钥目录

查看可用命令:openssl help

# ------ 所有可用工具 ------Standard commands asn1parse         ca                ciphers           cmscrl               crl2pkcs7         dgst              dhdhparam           dsa               dsaparam          ececparam           enc               engine            errstrgendh             gendsa            genpkey           genrsanseq              ocsp              passwd            pkcs12pkcs7             pkcs8             pkey              pkeyparampkeyutl           prime             rand              reqrsa               rsautl            s_client          s_servers_time            sess_id           smime             speedspkac             srp               ts                verifyversion           x509# man + 工具名称,显示某一命令的详细信息# man ciphers,显示如何配置密码套件# ------ 消息摘要命令 ------Message Digest commands (see the `dgst' command for more details)md4               md5               rmd160            shasha1# ------ 加密命令 ------Cipher commands (see the `enc' command for more details)aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecbaes-256-cbc       aes-256-ecb       base64            bfbf-cbc            bf-cfb            bf-ecb            bf-ofbcamellia-128-cbc  camellia-128-ecb  camellia-192-cbc  camellia-192-ecbcamellia-256-cbc  camellia-256-ecb  cast              cast-cbccast5-cbc         cast5-cfb         cast5-ecb         cast5-ofbdes               des-cbc           des-cfb           des-ecbdes-ede           des-ede-cbc       des-ede-cfb       des-ede-ofbdes-ede3          des-ede3-cbc      des-ede3-cfb      des-ede3-ofbdes-ofb           des3              desx              rc2rc2-40-cbc        rc2-64-cbc        rc2-cbc           rc2-cfbrc2-ecb           rc2-ofb           rc4               rc4-40seed              seed-cbc          seed-cfb          seed-ecbseed-ofb

获取算法的帮助信息

# 示例:获取 RSA 算法的帮助信息$ openssl rsa --help

证书格式及转换

证书格式

X.509 标准

X.509 标准来自国际电信联盟电信标准(ITU-T)的 X.500 标准。

X.509 标准是国际互联网工程任务组(IETF)的 PKIX 小组用来建设互联网的 PKI 公钥基础设施的标准。

HTTPS 中使用 X.509 的 PKI 标准。

X.509 标准目前最通用的版本为 X.509 V3 版本,引入了证书扩展的概念。

X.509 标准主要内容:证书的作用、证书文件的结构、证书管理方式、证书校验方式、证书的撤销等。

ASN.1 标准

ASN.1是国际电信联盟电信标准(ITU-T)定义的标准,用来结构化描述证书

ASN.1是一种抽象的数据结构,描述了复杂的对象,以及对象之间的关系。

????????????

X.509 标准定义了证书应该包含的内容,而为了让机器和人更好地理解和组织 X.509 标准,可以采用 ASN.1标准来描述 X.509 标准(或者说证书),ASN.1 类似于伪代码,是一种可理解的数据结构。

DER 编码、BER 编码、CER 编码、PEM 编码

  • 为了方便证书在互联网中传输,需要通过一个规则将 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 - 转换证书的各种格式
  • 阿里云文档:主流字证书都有哪些格式?

证书转换

PEM 和 DER 转换

使用 x509 子命令进行 PEM 和 DER 证书文件之间的格式转换:

# 从 PEM 转换到 DER:$ openssl x509 -in cert.pem -inform PEM -out cert.der -outform DER# 从 DER 转换到 PEM:$ openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM

参数:

  • -in,输入文件。
  • -out,输出文件。
  • -inform,输入文件的原有编码方式。
  • -outform,输出文件编码方式。

PKCS#12

PKCS#12 格式可以将证书和密钥对打包成一个文件,还可以对文件进行加密保护。

PKCS#12 文件后缀一般是 .pkcs12、.pfx、.p12。

通过 OpenSSL pkcs12 子命令将密钥对(privkey.pem)、服务器实体证书(cert.pem)、中间证书(chain.pem)转换成一个文件,并使用口令进行保护:

$ openssl pkcs12 \    -export -out cert.pfx \    -inkey privkey.pem -in cert.pem -certfile chain.pem

当需要使用证书时,可以从 cert.pfx 导出密钥对和证书,需要输入口令:

# 导出密钥对$ openssl pkcs12 -in cert.pfx -nodes -nocerts -out new_privkey.pem# 导出服务器实体证书$ openssl pkcs12 -in cert.pfx -nodes -clcerts -out new_cert.pem# 导出中间证书$ openssl pkcs12 -in cert.pfx -nodes -cacerts -out new_chain.pem

PKCS#7

PKCS#7 格式主要用来进行数字签名数据加密

PKCS#7 文件后缀一般是 .p7b 或 .p7c。

使用 crl2pkcs7 子命令生成 cert.p7b 文件:

$ openssl crl2pkcs7 -nocrl -certfile cert.pem -certfile chain.pem -out cert.p7b

参数:

  • -certfile 表示服务器证书。
  • 另一个 -certfile 表示中间件证书,不包含根证书。
  • -nocrl 表示不加载证书对应的 CRL 文件。

从 cert.p7b 文件中导出服务器证书文件和中间件证书文件:

# 导出完整的证书链文件,服务器实体证书在文件顶部,中间证书在文件底部$ openssl pkcs7 -print_certs -in cert.p7b -out fullchain.cert

获取线上证书

使用 OpenSSL 获取服务器实体证书、中间证书、根证书。

在线 Web 工具:SSL Certificate Checker - 分析网站证书的工具,可以在线下载证书及证书链

OpenSSL 获取线上证书

# 使用 s_client 获取线上证书,输出证书内容到控制台$ openssl s_client -connect www.github.com:443 -showcerts 2>&1 </dev/null# 下载服务器实体证书$ openssl s_client -connect www.sina.com.cn:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > www_cert.pem

输出内容如下:

CONNECTED(00000005)# 以下描述的是证书关系链# github.com -> DigiCert SHA2 Extended Validation Server CA -> DigiCert High Assurance EV Root CA# 根证书:DigiCert High Assurance EV Root CAdepth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CAverify return:1# 从编号 1 开始是中间证书:DigiCert SHA2 Extended Validation Server CAdepth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 Extended Validation Server CAverify return:1# 编号 0 服务器实体证书:github.comdepth=0 businessCategory = Private Organization, jurisdictionCountryName = US, jurisdictionStateOrProvinceName = Delaware, serialNumber = 5157550, C = US, ST = California, L = San Francisco, O = "GitHub, Inc.", CN = github.comverify return:1---Certificate chain# 编号 0 服务器实体证书:github.com 0 s:/businessCategory=Private Organization/jurisdictionCountryName=US/jurisdictionStateOrProvinceName=Delaware/serialNumber=5157550/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=github.com   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA-----BEGIN CERTIFICATE-----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-----END CERTIFICATE-----# 从编号 1 开始是中间证书# 这里没有输出根证书,根证书集成在浏览器中。 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA-----BEGIN CERTIFICATE-----MIIEtjCCA56gAwIBAgIQDHmpRLCMEZUgkmFf4msdgzANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowdTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTE0MDIGA1UEAxMrRGlnaUNlcnQgU0hBMiBFeHRlbmRlZCBWYWxpZGF0aW9uIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANdTpARR+JmmFkhLZyeqk0nQOe0MsLAAh/FnKIaFjI5j2ryxQDji0/XspQUYuD0+xZkXMuwYjPrxDKZkIYXLBxA0sFKIKx9om9KxjxKws9LniB8f7zh3VFNfgHk/LhqqqB5LKw2rt2O5Nbd9FLxZS99RStKh4gzikIKHaq7q12TWmFXo/a8aUGxUvBHy/Urynbt/DvTVvo4WiRJV2MBxNO723C3sxIclho3YIeSwTQyJ3DkmF93215SF2AQhcJ1vb/9cuhnhRctWVyh+HA1BV6q3uCe7seT6Ku8hI3UarS2bhjWMnHe1c63YlC3k8wyd7sFOYn4XwHGeLN7x+RAoGTMCAwEAAaOCAUkwggFFMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2MDQwMgYEVR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMB0GA1UdDgQWBBQ901Cl1qCt7vNKYApl0yHU+PjWDzAfBgNVHSMEGDAWgBSxPsNpA/i/RwHUmCYaCALvY2QrwzANBgkqhkiG9w0BAQsFAAOCAQEAnbbQkIbhhgLtxaDwNBx0wY12zIYKqPBKikLWP8ipTa18CK3mtlC4ohpNiAexKSHc59rGPCHg4xFJcKx6HQGkyhE6V6t9VypAdP3THYUYUN9XR3WhfVUgLkc3UHKMf4Ib0mKPLQNa2sPIoc4sUqIAY+tzunHISScjl2SFnjgOrWNoPLpSgVh5oywM395t6zHyuqB8bPEs1OG9d4Q3A84ytciagRpKkk47RpqF/oOi+Z6Mo8wNXrM9zwR4jxQUezKcxwCmXMS1oVWNWlZopCJwqjyBcdmdqEU79OX2olHdx3ti6G8MdOu42vi/hw15UJGQmxg7kVkn8TUoE6smftX3eg==-----END CERTIFICATE--------# 服务器证书Server certificatesubject=/businessCategory=Private Organization/jurisdictionCountryName=US/jurisdictionStateOrProvinceName=Delaware/serialNumber=5157550/C=US/ST=California/L=San Francisco/O=GitHub, Inc./CN=github.comissuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 Extended Validation Server CA---No client certificate CA names sentServer Temp Key: ECDH, X25519, 253 bits---SSL handshake has read 3541 bytes and written 285 bytes---New, TLSv1/SSLv3, Cipher is ECDHE-RSA-CHACHA20-POLY1305Server public key is 2048 bitSecure Renegotiation IS supportedCompression: NONEExpansion: NONENo ALPN negotiatedSSL-Session:    Protocol  : TLSv1.2    Cipher    : ECDHE-RSA-CHACHA20-POLY1305    Session-ID: BA6DB13E4B6CEC5B9AF3ABD52BFF096A05BC829EDF6A4D48075A42ACFC77EFC8    Session-ID-ctx:    Master-Key: D1B878609C84F45DDC44DCCE1DF2EEEFC61BF87593D7E60A8C776BAB3FB06CD6F3880BF691E075F8A6D5300CE906FE07    Start Time: 1557454972    Timeout   : 7200 (sec)    Verify return code: 0 (ok)---poll error%

使用 Shell 命令拆分服务器实体证书和中间证书

使用 Shell 命令提取证书链中的服务器实体证书和中间证书:

$ openssl s_client -connect www.github.com:443 -shwocerts 2>&1 </dev/null \  | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' \  > www_fullchain.pem

完整的证书链文件保存在 www_fullchain.pem 文件中,然后将 www_fullchain.pem 拆分成各个文件:

❌ 注:这里拆分文件存在命令行语法错误,待解决。

$ cat www_fullchain.pem  | awk 'split_after==1{n++;split_after=0} \    /-----END CERTIFICATE-----/ {split_after=1} \    {print > "www_cert" n ".pem"}'# 重命名中间证书,在本列中中间证书只有一个$ mv www_cert1.pem www_chain.pem# 查看生成的各个文件$ tree.|—— www_cert.pem  # 服务器实体证书|—— www_chain.pem # 中间证书|—— www_fullchain.pem # 完整证书链文件

获取根证书

首先,找到证书链中最底部的一张证书(即根证书签发的第一张中间证书),然后通过证书中包含的 CA Issures 信息获取上一级证书(即根证书)的地址。

# 在本例中 www_chain.pem 是证书链中最底部的一张证书,它的上一级证书就是根证书$ openssl x509 -in www_chain.pem -noout -text | grep "CA Issuers"# 下载根证书文件$ wget http://apps.identrust.com/roots/dstrootcax3.p7c -O DST_ROOT.p7c# 转换成 PEM 格式$ openssl pkcs7 -inform der -in DST_ROOT.p7c -print_certs -out DST_ROOT.pem# 检查证书签发者$ openssl x509 -in DST_ROOT.pem -issuer

导入证书到根证书库

如何更新系统的根证书?

使用 Mozilla 根证书库更新系统证书库

使用 Mozilla 根证书库创建可信证书库的两种方式:

  1. 从 Mozilla CA Certificate Store 获取开源的可信证书库:Source file with all of the included root certificates。下载完成后,可以使用 Perl 脚本或者 Go 脚本将 certdata.txt 文件转换为 PEM 格式。
  2. 使用 Curl 获取最新的 PEM 格式的可信证书库:CA certificates extracted from Mozilla。

在 Linux 系统中,可以使用 Mozilla 根证书库更新系统的根证书库。

  1. 下载 Mozilla 根证书库。

    # 使用 Curl 的 mk-ca-bundle 工具可以从 Mozilla 下载根证书,并转换为各个 CA 机构的根证书文件$ wget https://raw.githubusercontent.com/curl/curl/master/lib/mk-ca-bundle.pl$ chmod 0777 mk-ca-bundle.pl$ ./mk-ca-bundle.pl

    CA 机构的根证书文件存放在 /usr/share/ca-certificates/mozilla 目录下。

    同时 /etc/ca-certificates.conf 文件也会更新,该文件包含了 Mozilla 各个根证书文件的列表。

  2. 使用 update-ca-certificates 工具将 Mozilla 的各个根证书文件同步到系统的根证书库中。

    update—certificates 工具会读取 /etc/ca-certificates.conf 文件,找到所有 Mozilla 配置的根证书文件,然后将 /usr/share-certificates/mozilla 下的根证书文件复制到 /etc/ssl/certs 目录下,同时 /etc/ssl/certs-certificates.crt 文件也会更新,该文件比较大,包含了所有的根证书文件,相当于所有根证书文件的集合。

    # 更新系统的证书库$ update-ca-certificates
  3. 自签名证书同步到系统根证书库中。

    $ mkdir /usr/local/share/ca-certificates/extra# 拷贝自签名证书,文件后缀 crt $ cp self-ertificate.crt /usr/local/share/ca-certificates/extra$ update-ca-certificates

OpenSSL 管理 CSR

服务器实体为了证明自己的身份,需要向 CA 机构申请证书。

在申请证书之前,必须先生成一个 CSR 文件,CSR 文件是要求 CA 给证书签名的一种正式申请,该文件中包含申请证书的实体的公钥以及该实体的相关信息。然后再将 CSR 文件发送给 CA 机构。

CSR 文件标准:PKCS#10 标准。

推荐阅读:花生壳:SSL 证书请求文件 (CSR) 生成指南

生成 CSR 文件

交互式

# 1.使用 genrsa 命令生成密钥长度为 2048 比特的 RSA 密钥对$ openssl genrsa -out mykey.pem 2048# 2.使用私钥(mykey.pem)生成 CSR 文件(mycsr.pem)$ sudo openssl req -new -key mykey.pem -out mycsr.pemEnter pass phrase for fd.key:You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.# ⚠️ 输入一个点(.),该字段为空。键入回车键,则设置为默认值。-----Country Name (2 letter code) [AU]:CN # 国家State or Province Name (full name) [Some-State]:Shanghai # 省市Locality Name (eg, city) []:Shanghai # 地区Organization Name (eg, company) [Internet Widgits Pty Ltd]:Shanghai Clumsiest Information Co., Ltd. # 组织机构Organizational Unit Name (eg, section) []: # 单位部门Common Name (e.g. server FQDN or YOUR name) []: # 通用名Email Address []:clumsiest@outlook.com # 邮箱地址Please enter the following 'extra' attributes # 质询密码,留空to be sent with your certificate requestA challenge password []:.An optional company name []:.

非交互式

使用 OpenSSL req 子命令,通过非交互式方式同时生成密钥对和 CSR 文件,命令如下:

# -------------- 示例一 --------------$ openssl req \    -new -sha256 -newkey rsa:2048 -nodes \    -subj '/CN=www1.example.com,www2.example.com/O=Test, Inc./C=CN/ST=Beijing/L=Haidian' \    -keyout example_key.pem -out example_csr.pem# -------------- 示例二 --------------# 1. 如果想自动生成 www.example.com 的CSR文件,可以先创建一个 fd.cnf 文件:[req]prompt = nodistinguished_name = dnreq_extensions = extinput_password = PASSPHRASE[dn]CN = www.feistyduck.comemailAddress = webmaster@feistyduck.com0 = Feisty Duck LtdL = LondonC = GB[ext]subjectAltName = DNS:www.example.com,NDS:example.com# 2. 使用如下命令直接创建 CSR 文件$ openssl req -new -config fd.cnf -key example_key.pem -out example_csr.csr

参数:

  • -sha256 表示证书使用 sha256 算法生成摘要(Hash 值)然后计算签名。
  • -newkey 表示生成一个 2048 比特的 RSA 密钥对文件。
  • -subj 参数表示手动设置 CSR 请求信息,不用进行交互式输入。
  • -keyout 表示输出密钥对文件。
  • -out 表示输出 CSR 文件。

用当前证书生成 CSR 文件

更新一张证书,并且不想对里面的信息作任何更改:

$ openssl x509 -x509toreq -in example_cert.crt -out example_csr.pem -signkey example_mykey.pem

查看 CSR 文件

使用 OpenSSL req 子命令查看 CSR 文件内容:

$ openssl req -in example_csr.pem -noout -text

输出 CSR 文件示例:

Certificate Request: # 证书请求信息    Data:        Version: 0 (0x0) # PKCS#10 标准的版本号        Subject: CN=www1.example.com,www2.example.com, O=Test, Inc., C=CN, ST=Beijing, L=Haidian # 服务器主体可分辨名称 DN        Subject Public Key Info: # 服务器密钥对的公钥            Public Key Algorithm: rsaEncryption                Public-Key: (2048 bit) # 密钥长度 2048 比特                Modulus:                    00:d1:72:55:de:64:97:c8:8e:6e:e1:34:0c:52:d5:                    68:03:83:84:61:52:4a:64:ed:a8:d0:47:35:1f:89:                    66:4a:7d:82:66:37:55:3c:4a:26:6e:06:c0:da:56:                    56:dc:36:fa:7c:df:70:22:c8:f2:25:47:46:ea:9c:                    88:e9:9e:09:6b:98:e3:7e:59:a5:fb:44:47:2b:92:                    c4:2e:ca:be:1c:2e:7b:c5:4a:cb:66:12:dd:34:81:                    37:b1:21:d1:14:de:2c:e0:08:7d:cd:0a:98:1f:de:                    ab:eb:77:5f:7e:bc:3e:84:cf:01:c7:c4:97:ee:e5:                    00:ec:61:12:3e:93:76:cd:f8:0c:ac:92:77:52:01:                    c4:d2:de:0a:44:ff:fb:59:92:4a:7e:66:32:4d:2c:                    1c:17:c1:7e:36:0b:d8:97:2a:89:5e:d4:0c:a2:a8:                    81:67:36:d3:59:93:e1:08:84:06:61:45:83:7e:8b:                    7b:f6:1b:b9:e0:c3:d8:66:ba:a1:01:4f:f0:7c:8a:                    02:ab:0e:4d:4b:9d:b5:07:1b:db:b4:1d:f4:85:9e:                    a1:0e:84:22:e6:fc:48:cb:8b:34:49:1f:8e:d6:25:                    b2:7a:6e:70:14:02:a3:13:f5:ad:31:af:f4:87:87:                    44:89:31:16:d8:7b:79:1a:30:90:bf:fa:bd:2a:e1:                    7f:89                Exponent: 65537 (0x10001)        Attributes: # 可选信息            a0:00    Signature Algorithm: sha256WithRSAEncryption # 签名算法和签名值         70:73:53:1f:5e:47:82:ea:88:02:30:7a:d9:bc:86:3c:2c:77:         fb:d0:ee:09:87:4d:e0:05:4e:b3:73:89:f1:00:77:b8:a8:31:         c8:68:dd:73:45:b2:f8:9b:c6:3e:03:4a:b0:5f:fd:d4:cd:a5:         7a:18:3b:0b:ac:99:14:76:a6:8d:3d:e7:43:56:a2:a4:0e:5b:         a4:22:ab:69:1f:67:7b:ea:3d:ab:df:2b:c0:a6:8c:f0:9b:df:         cd:11:18:88:bc:37:87:b9:b3:58:2c:de:17:3e:a9:a1:52:43:         34:b1:2b:40:15:74:ef:4c:17:fb:23:ef:17:a1:5f:99:cd:fa:         6f:6a:ef:8d:61:bc:23:2a:23:2b:68:9e:f5:ab:5e:cd:17:ef:         d3:f3:6f:fc:ad:cb:4e:c6:36:4e:cb:1d:6c:3c:2d:ec:13:9f:         dc:f1:86:50:66:7e:44:f7:70:27:6b:48:27:18:54:95:6a:39:         47:32:10:7e:5d:07:4e:63:32:3a:16:c8:c6:d0:3e:fa:b8:56:         78:fd:50:db:cd:44:79:9e:47:a5:05:98:3c:3d:90:4b:65:d7:         1c:10:5c:8e:ec:25:3e:f1:a4:6e:03:33:12:65:f1:19:e6:ea:         05:14:c5:55:e2:b9:d9:70:2f:54:8c:9a:b6:f3:71:70:fa:34:         ee:8c:0f:8e

在线 Web 工具:CSR Decoder - 解析 CSR 文件的一个小工具

校验 CSR 签名

CA 会使用服务器实体的公钥验证 CSR 文件的签名,确保 CSR 文件没有被篡改。

$ openssl req -in example_csr.pem -noout -verify -key example_key.pemverify OK

CSR 格式转换

# PEM 格式转换为 DER 格式$ openssl req -in example_csr.pem -out example_csr.der -outform DER# DER 格式转换为 PEM 格式$ openssl req -in example_csr.der -inform DER -out example_csr.pem -outform PEM 

OpenSSL 生成自签名证书

{% note warning %}

请勿在生产环境中使用自签名证书,自签名证书的唯一目的是测试。

{% endnote %}

使用 OpenSSL 管理密钥和证书的步骤:

  • 通常情况下,使用 2048 位的 RSA 算法,因为 DSA 算法因效率问题会被限制在 1024 位,而 ECDSA 算法则还没有被大部分 CA/客户端支持。

如何生成自签名证书:

方式一:同时生成密钥对和自签名证书

执行以下 OpenSSL 命令生成自签名证书:

$ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes...# 这里会以交互式方式让你设置相关参数

方式二:通过密钥对创建自签名证书

使用密钥对交互式创建自签名证书

# 1.使用 genrsa 命令生成 2048 比特的 RSA 密钥对$ openssl genrsa -out example_key.pem 2048# 2.通过密钥对生成证书$ openssl req -new -x509 -days 365 -key example_key.pem -out example_cert.pem...# 这里会以交互式方式让你设置相关参数

注:了解 RSA 算法的更多实践,参考之前写的博客:密码学—密码算法与协议

使用密钥对非交互式创建自签名证书

# 1.使用 genrsa 命令生成 2048 比特的 RSA 密钥对$ openssl genrsa -out example_key.pem 2048# 2. 生成证书$ openssl req -new -x509 -days 365 -key example_key.pem -out example_cert.pem -subj "/C=GB/L=London/O=Feisty Duck Ltd/CN=www.example.com"

方式三:通过 CSR 文件创建自签名证书

使用 OpenSSL x509 子命令生成自签名证书:

# 1.非交互式方式同时生成密钥对和 CSR 文件$ openssl req \    -new -sha256 -newkey rsa:2048 -nodes \    -subj '/CN=*.example.com,example.com/O=Test, Inc./C=CN/ST=Beijing/L=Haidian' \    -keyout example_key.pem -out example_csr.pem# 2.创建扩展文件 certext.ext,以在一张证书中支持多个域名(可选)# 默认情况下,OpenSSL 创建的证书只包含一个公用名而且只能设置一个主机名。$ echo "subjectAltName=DNS:*.example.com,DNS:example.com" >>certext.ext # 3.生成自签名证书$ openssl x509 -req -days 365 -in example_csr.pem \   -signkey example_key.pem -out example_cert.pem \   -extfile certext.ext

参数:

  • -days 参数表示证书的有效期。
  • -in 表示 CSR 文件。
  • -signkey 表示密钥对的公钥。
  • -out 表示输出的证书文件。
  • -extfile 表示引用一个扩展文件。

OpenSSL 查看证书

{% note default %}
数字证书基本格式见文章末尾。
{% endnote %}

使用 x509 子命令查看证书内部结构

# 查看证书完整信息$ openssl x509 -in cert.pem -text -noout# 查看证书包含的公钥$ openssl x509 -in cert.pem -pubkey# 查看哪个 CA 机构签发了证书$ openssl x509 -in cert.pem -issuer# 查看证书的有效期$ openssl x509 -in cert.pem -enddate

参数:

  • -in 表示要查看的证书文件。
  • -text 表示打印详细信息。
  • -noout 表示不打印编码后的证书内容,以减少信息干扰。

使用 x509 子命令查看服务器实体证书

# 查看服务器实体证书$ openssl x509 -in 2056942_www.andy0570.com.pem -text -noout# 输出内容如下:Certificate:    Data:            # 证书版本        Version: 3 (0x2)        # 序列号        Serial Number:            0b:5b:23:58:48:f7:92:61:01:88:07:4b:2f:19:5e:4e    Signature Algorithm: sha256WithRSAEncryption            # 证书签发者:Encryption Everywhere DV TLS CA        Issuer: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=Encryption Everywhere DV TLS CA - G1        Validity                # 证书有效期            Not Before: Apr 13 00:00:00 2019 GMT            Not After : Apr 12 12:00:00 2020 GMT        # 证书的域名        Subject: CN=www.andy0570.com        # 证书公钥信息        Subject Public Key Info:                # 证书公钥算法:RSA            Public Key Algorithm: rsaEncryption                # 公钥长度:2048 比特                Public-Key: (2048 bit)                # 公钥 n 信息                Modulus:                    00:c7:1a:29:48:57:ed:de:11:b0:ff:8a:ac:36:d0:                    fb:3f:23:cf:27:41:2b:99:cd:a8:7a:61:34:2e:b8:                    0a:00:16:cc:b5:e0:7c:21:63:90:75:05:de:6f:1c:                    1d:df:72:b7:0e:63:96:5d:e3:e1:cc:5b:38:87:9b:                    bf:0f:6d:fd:a1:53:c4:03:19:b6:77:40:30:75:91:                    09:a3:68:ff:1d:fc:8a:e3:b7:f7:e9:d5:8b:1b:56:                    48:5a:c6:24:10:8e:53:9d:11:f2:22:8b:a5:c8:8c:                    9e:02:3b:ff:fd:3e:90:93:8c:b8:d4:f0:7d:42:95:                    9f:b6:3f:3a:f2:44:de:cd:7a:cd:0a:2a:83:a3:4b:                    d6:e7:b9:6e:a2:05:fc:5e:7e:6d:12:ed:9f:db:3b:                    96:52:58:06:eb:da:15:9b:21:ea:f1:8c:50:94:bc:                    8c:58:e6:f7:d3:3a:06:8b:85:9d:b2:31:19:94:1e:                    88:99:46:e8:88:58:2b:37:22:71:be:8a:c6:7f:76:                    23:92:d9:60:4d:ba:c7:33:38:ac:38:e4:7b:d1:7d:                    20:c5:8d:19:66:50:41:74:51:a5:d1:36:92:00:d2:                    17:5c:ab:6b:e1:d6:bd:16:5a:7b:8f:41:dc:61:ec:                    2e:88:c0:aa:ef:de:67:9f:9b:24:95:cd:7c:23:c9:                    53:2f                # 公钥 e 信息                Exponent: 65537 (0x10001)        # 证书扩展        X509v3 extensions:            # CA 密钥标识符            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                        # 使用者密钥标识符            X509v3 Subject Key Identifier:                6C:60:56:C3:E3:41:39:6C:F8:03:74:52:13:92:F6:1B:F0:52:0B:15            # 使用者可选名称            X509v3 Subject Alternative Name:                DNS:www.andy0570.com, DNS:andy0570.com            # 密钥使用扩展,证书密钥的用法            X509v3 Key Usage: critical                Digital Signature, Key Encipherment # 数字签名、密钥协商            # 扩展密钥用法,表明该证书可以进行 HTTPS 网站服务器身份校验            X509v3 Extended Key Usage:                TLS Web Server Authentication, TLS Web Client Authentication            # 证书策略            X509v3 Certificate Policies:                Policy: 2.16.840.1.114412.1.2                  CPS: https://www.digicert.com/CPS                Policy: 2.23.140.1.2.1                        # CA 信息,包括 CA 的 OCSP 地址、CA 官网地址            Authority Information Access:                OCSP - URI:http://ocsp.dcocsp.cn                CA Issuers - URI:http://cacerts.digicert.com/EncryptionEverywhereDVTLSCA-G1.crt                        # 基本约束,该证书不是 CA 证书,不能签发其他证书            X509v3 Basic Constraints:                CA:FALSE            1.3.6.1.4.1.11129.2.4.2:                ......v.......X......gp.....j..a/.....G0E. 0m.6.q....Os4.......8K.(.S.......!....2aP....".N..../..O.S#m%.;.\.m.v.^.s..V...6H}.I.2z.........u..qEX...j..\*.....G0E. ..EE...qu....K.......v...p<.Z....!....)..[...5...t..4eOR.qaV{.9...@    # 签名算法(SHA256)和签名值    Signature Algorithm: sha256WithRSAEncryption         06:b1:75:bf:f1:64:6a:19:a0:fd:c9:05:d2:15:bd:f0:34:e8:         2e:30:0b:01:d8:08:00:46:67:5e:63:67:3c:dd:02:54:c7:05:         f1:f6:98:d6:38:62:c6:c9:73:fd:76:1d:47:63:db:11:79:82:         d7:89:0e:4c:47:74:36:a3:37:05:7c:c5:9c:9e:10:12:6c:ab:         ea:56:07:eb:a5:78:b3:73:df:fb:53:c8:1b:66:84:8a:42:3b:         5e:f0:a4:3d:75:e4:c5:b6:af:cd:b4:e9:0d:40:f9:b9:dd:fb:         3c:bf:01:19:b5:93:27:e1:7b:d7:6d:17:3f:11:b9:8e:22:12:         ee:0c:78:d4:4f:26:07:b2:27:0c:4c:74:98:24:6e:f4:25:de:         cd:29:dd:99:f7:19:de:43:74:4d:ae:2c:f9:25:e6:39:30:99:         d2:b9:74:94:85:a7:c8:99:75:e6:f0:66:36:7f:f7:4f:8a:ea:         92:dd:91:7d:fa:85:af:34:c1:5b:b9:76:74:af:0c:98:3e:20:         aa:6c:3a:85:d4:03:7f:5b:ec:67:7b:45:90:a9:bb:11:81:94:         86:f1:e8:f2:56:27:2e:40:86:30:59:83:9b:10:1d:c6:2c:3a:         74:d8:88:6d:2b:84:14:3a:56:1d:03:33:24:15:b2:19:44:88:         f5:1e:03:30

使用 x509 子命令查看中间证书

$ openssl x509 -in cert.pem -text -noout  

使用 x509 子命令查看根证书

$ openssl x509 -in  DST_ROOT.pem -noout -text   

校验 CRL

手动校验 CRL

下载 CRLs 文件,手动查看服务器实体证书的序列号是否存在于 CRLs 中,如果存在说明证书被吊销了,这种方式不校验 CRLs 的签名。
Let’ s Encrypt 认为 CRL 的作用已经不大,所以其签发的证书并不包含CRL分发点信息。

# 下载服务器实体证书$ openssl s_client -connect www.sina.com.cn:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > www_cert.pem# 找到服务器实体证书的 CRL 分发点$ openssl x509 -in www_cert.pem -noout -text | grep "crl"# 输出 CRL 分发点地址URI:http://cdp1.digicert.com/GeoTrustRSACA2018.crl# 下载 CRLs 文件$ wget "http://cdp1.digicert.com/GeoTrustRSACA2018.crl"# 查看 CRLs 文件内容$ openssl crl -inform DER -text -noout -in GeoTrustRSACA2018.crl# 由于文件太长了,这里保存到 crl.text 文件中$ openssl crl -inform DER -text -noout -in GeoTrustRSACA2018.crl > crl.text

查看 CRLS 文件内容:

Certificate Revocation List (CRL):        # 版本号,必须是 V2 版本        Version 2 (0x1)    # 签名算法:SHA256    Signature Algorithm: sha256WithRSAEncryption        # CRL 签发者:GeoTrust RSA CA        Issuer: /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=GeoTrust RSA CA 2018        # CRLs 本次更新时间        Last Update: May  9 20:30:01 2019 GMT        # CRLs 下次更新时间        Next Update: May 16 20:30:01 2019 GMT        # CRL 扩展        CRL extensions:            X509v3 Authority Key Identifier:                 keyid:90:58:FF:B0:9C:75:A8:51:54:77:B1:ED:F2:A3:43:16:38:9E:6C:C5            X509v3 CRL Number:                 549# 被吊销的证书列表Revoked Certificates:    # 服务器实体证书的序列号    Serial Number: 0E0072EBF08A8C7E0429798AD5BA850D        # 服务器实体证书的吊销时间        Revocation Date: Nov 22 10:28:31 2017 GMT        CRL entry extensions:            # 证书被吊销的原因            X509v3 CRL Reason Code:                 Key Compromise    Serial Number: 02E6BE4950D0BAE5205926AA3C350C92        Revocation Date: Dec  1 00:26:42 2017 GMT    # ...    # (略去 n 张证书列表)    # ...    Serial Number: 0A6D5EF45E060221840A8A97FF36D1F5        Revocation Date: May  9 20:06:16 2019 GMT        CRL entry extensions:            X509v3 CRL Reason Code:                 Key Compromise    # CRLs 签名算法:SHA256 和签名值    Signature Algorithm: sha256WithRSAEncryption         15:9a:56:e1:ff:de:63:bc:66:af:47:41:c9:07:83:cf:50:0c:         24:16:04:0c:ad:e1:c2:25:83:c2:de:ef:36:26:3c:1d:04:07:         b2:91:e5:3e:8e:39:16:4a:e4:0c:3f:cc:3d:48:16:db:2d:f4:         01:cf:36:3a:68:c1:75:a7:d2:ab:59:88:63:d5:52:f9:b5:26:         b9:06:c5:96:b0:c6:1a:94:23:9c:88:b0:75:89:1a:4b:54:2f:         e2:32:70:ec:6e:11:e1:5d:dd:e6:90:52:b2:78:57:bf:fa:c1:         ef:0b:6f:da:e3:45:5d:30:f6:60:40:b0:fe:82:f3:3b:b8:7b:         18:2f:9e:ed:c7:58:5e:23:59:e0:81:a8:25:fb:27:d3:63:9c:         56:e2:b0:c4:61:52:0c:08:a1:a1:c8:ae:55:44:71:0c:9a:c6:         f5:7a:ad:0c:19:78:d2:50:2d:23:d6:7d:1c:6a:74:2d:c6:8f:         7f:d5:9a:2a:e9:07:47:f1:84:a6:5e:80:0f:06:cb:a3:1f:2a:         1b:16:bf:29:c1:48:36:10:bf:50:ea:60:db:fc:d0:25:74:f2:         60:e9:2f:d8:4a:28:0a:46:6a:a3:b0:f2:5c:bc:18:c9:36:e6:         be:e9:cb:45:c3:b9:21:07:65:f9:92:21:3f:6e:e0:a4:e0:68:         21:9f:17:2b

自动校验 CRL

通过 OpenSSL verify 子命令自动校验证书的吊销状态:

# 下载证书链文件$ openssl s_client -connect www.sina.com.cn:443 -showcerts  2>&1 </dev/null \   | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'    \   > www_fullchain.pem# 拆分证书文件,www_cert.pem 是服务器实体证书,www_chain1.pem 是中间证书$ cat www_fullchain.pem  | awk 'split_after==1{n++;split_after=0} \    /-----END CERTIFICATE-----/ {split_after=1} \    {print > "www_cert" n ".pem"}'# 重命名中间证书,在该例中,中间证书只有一个。$ mv www_cert1.pem www_chain.pem# 找到服务器实体证书的 CRL 分发点$ openssl x509 -in www_cert.pem -noout -text | grep "crl"# 输出 CRL 分发点地址URI:http://gn.symcb.com/gn.crl# 下载 CRLs 文件$ wget "http://gn.symcb.com/gn.crl"# 将 CRLs 文件转换为 PEM 格式$ openssl crl -inform DER -in gn.crl -outform PEM -out crl.pem# 合并中间证书和 CRLs 文件$ cat www_chain.pem crl.pem > crl_chain.pem# 校验,-CAfile 表示完整证书链$ openssl verify -crl_check -CAfile crl_chain.pem www_cert.pem# 输出 ok 表示服务器实体证书没有被吊销www_cert.pem: OK

比较服务器实体证书的签发者和 CRLs 的签发者

# 查询服务器实体证书的签发者$ openssl x509 -in www_cert.pem -issuer -pubkey# 输出issuer=C = US, O = GeoTrust Inc., CN = GeoTrust SSL CA - G3# 查询 CRLs 的签发者$ openssl crl -inform DER  -noout -in gn.crl  -issuer   # 输出issuer=C = US, O = GeoTrust Inc., CN = GeoTrust SSL CA - G3

校验 OCSP

校验 Let‘s Encrypt 的 OCSP 服务

# 下载服务器实体证书:letsencrypt.org$ openssl s_client -connect www.letsencrypt.org:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > www_cert.pem# 从服务器实体证书中获取 OCSP 的地址$ openssl x509 -in www_cert.pem -noout -ocsp_uri# 输出 OCSP URL 地址http://ocsp.int-x3.letsencrypt.org# 校验 OCSP  $ openssl ocsp -issuer chain.pem -cert www_cert.pem -CAfile chain.pem \   -no_nonce --text -url  http://ocsp.int-x3.letsencrypt.org \   -header Host=ocsp.int-x3.letsencrypt.org

校验 GeoTrust 的 OCSP 响应

Let‘s Encrypt 的 OCSP 响应不包含 Certificate 信息,而 GeoTrust 的 OCSP 响应包含 Certificate 信息:

# 1.下载新浪网服务器实体证书,www.sina.com.cn$ openssl s_client -connect www.sina.com.cn:443 2>&1 < /dev/null | sed -n '/-----BEGIN/,/-----END/p' > www_cert.pem# 2. 下载中间证书# 2.1 找到该服务器实体证书的中间证书的 URL$ openssl x509 -in www_cert.pem -noout -text | grep "CA Issuers"CA Issuers - URI:http://cacerts.geotrust.com/GeoTrustRSACA2018.crt# 2.2下载该中间证书文件$ wget http://cacerts.geotrust.com/GeoTrustRSACA2018.crt -O GeoTrustRSACA2018.crt# 2.3 从 DER 转换到 PEM$ openssl x509 -in GeoTrustRSACA2018.crt -inform DER -out GeoTrustRSACA2018.pem -outform PEM# 3. 校验 GeoTrust 的 OCSP 响应$ openssl ocsp -issuer GeoTrustRSACA2018.pem -cert www_cert.pem  \   -url  http://ocsp.digicert.com -CAfile GeoTrustRSACA2018.pem --text -no_nonce

{% note danger %}

以上方法实测存在问题。

{% endnote %}

校验 OCSP 封套

OCSP 封套相比标准 OCSP 来说,不是由浏览器发出 OCSP 请求,而是由证书部署者即服务器负责发出 OCSP 请求

说明,并不是所有的 HTTPS 网站都支持 OCSP 封套。

使用不支持 OCSP 封套的 HTTPS 网站进行演示

$ openssl s_client -connect www.baidu.com:443 -status -tlsextdebug < /dev/null 2>&1 \   | grep -i "OCSP response"# 如果服务器不支持 OCSP 封套,则输出OCSP response: no response sent

使用支持 OCSP 封套的 HTTPS 网站进行演示

$ openssl s_client -connect letsencrypt.org:443 -status -tlsextdebug < /dev/null 2>&1

输出内容如下:

CONNECTED(00000005)TLS server extension "renegotiation info" (id=65281), len=10001 - <SPACES/NULS>TLS server extension "EC point formats" (id=11), len=40000 - 03 00 01 02                                       ....TLS server extension "session ticket" (id=35), len=0TLS server extension "status request" (id=5), len=0depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3verify return:1depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3verify return:1depth=0 CN = www.letsencrypt.orgverify return:1OCSP response:======================================# 重点关注以下内容OCSP Response Data:    OCSP Response Status: successful (0x0)    Response Type: Basic OCSP Response    Version: 1 (0x0)    Responder Id: C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3    Produced At: May  3 22:10:00 2019 GMT    Responses:    Certificate ID:      Hash Algorithm: sha1      Issuer Name Hash: 7EE66AE7729AB3FCF8A220646C16A12D6071085D      Issuer Key Hash: A84A6A63047DDDBAE6D139B7A64565EFF3A8ECA1      Serial Number: 03E1CE2C0324F9CA93417FC8886F87F34857    Cert Status: good    This Update: May  3 22:00:00 2019 GMT    Next Update: May 10 22:00:00 2019 GMT    Signature Algorithm: sha256WithRSAEncryption         0d:de:d1:a8:f7:d2:20:19:76:dd:29:47:19:c1:07:ed:4e:8f:         fb:4f:9f:10:2f:b7:c7:74:43:17:27:61:9f:b8:f5:d9:76:f1:         49:b0:ee:b3:14:a9:a9:e0:9b:78:86:79:db:47:d6:21:04:e5:         ef:d4:9d:a9:98:0c:e0:7c:3d:08:4c:34:7b:ba:59:0e:f9:29:         81:c8:dc:ec:76:f4:29:e3:9f:56:27:bb:0b:8d:4e:a1:7e:75:         51:55:b2:04:79:0f:4e:be:f1:9d:69:d8:60:49:90:4f:de:d6:         33:e0:45:e9:cd:0b:97:01:d8:ee:cf:2f:d1:4c:40:bb:b0:26:         cf:b4:bf:fb:02:2e:7a:8f:f1:87:a4:29:ef:6e:0f:df:e2:78:         cd:3a:b6:8d:c7:8c:d4:31:83:eb:63:28:98:1f:bd:ee:8f:03:         fe:42:97:79:3a:20:4e:d4:9b:f6:e3:b4:2e:ad:df:83:6f:3a:         d4:53:e0:e3:a1:0d:a5:79:4c:4d:b0:3e:03:e6:7e:9d:2c:4c:         83:65:e7:08:b0:86:71:c7:d0:57:41:3c:3d:6a:83:00:e5:57:         51:f8:13:50:8a:21:5a:69:68:c7:6b:c4:96:e9:6c:b1:b9:82:         c1:a1:c7:04:3f:c2:d0:dd:4e:20:1c:51:b3:55:8e:11:d4:a8:         e3:c4:7c:d0======================================---Certificate chain 0 s:/CN=www.letsencrypt.org   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3   i:/O=Digital Signature Trust Co./CN=DST Root CA X3---Server certificate-----BEGIN CERTIFICATE-----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-----END CERTIFICATE-----subject=/CN=www.letsencrypt.orgissuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3---No client certificate CA names sentServer Temp Key: ECDH, P-256, 256 bits---SSL handshake has read 4237 bytes and written 335 bytes---New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384Server public key is 2048 bitSecure Renegotiation IS supportedCompression: NONEExpansion: NONENo ALPN negotiatedSSL-Session:    Protocol  : TLSv1.2    Cipher    : ECDHE-RSA-AES256-GCM-SHA384    Session-ID: EFDCAF717B3A840A2E3A9808F90028B29F2B8CD6CEEF52AC5CAE92E67D7C14ED    Session-ID-ctx:    Master-Key: C758A1EEA29D5051A00E74FDA649AE7A3DC84370563763B41FAAD3136D22C5F2BED802065E4FB3664C95EE35D0D4172D    TLS session ticket lifetime hint: 7200 (seconds)    TLS session ticket:    0000 - 00 00 0c e0 5e 86 4b e0-d7 0f a8 8e 1f f3 89 41   ....^.K........A    0010 - 8a 16 c0 33 f1 69 c7 38-d7 9a f7 93 bc 15 2f 8a   ...3.i.8....../.    0020 - d2 56 85 27 3d 0a 98 1c-04 91 ed d8 0c f4 87 23   .V.'=..........#    0030 - 2c 1f 1f 61 fc d3 63 57-34 19 33 bb 2a 17 0f a0   ,..a..cW4.3.*...    0040 - 30 51 7d ef db fc e7 b3-57 64 64 f8 6b 36 0b f5   0Q}.....Wdd.k6..    0050 - 38 93 77 9e bb 12 f0 1a-75 d6 47 6b dc 8b 49 de   8.w.....u.Gk..I.    0060 - 51 9a d1 bd e0 00 5f e8-8c f7 48 0e b9 03 07 73   Q....._...H....s    0070 - b6 33 a8 9b 35 3e a1 43-06 7e 63 be 26 16 35 c1   .3..5>.C.~c.&.5.    0080 - 99 56 d5 15 f1 47 c9 e9-3d c9 89 d9 d4 1c 00 6b   .V...G..=......k    0090 - f8 e6 0f e6 96 8c 4e ee-94 2e 6d 9a f6 04 e1 8f   ......N...m.....    00a0 - c3 5e c9 6a f0 2d bc e3-84 21 47 c5 b1 65 cb ff   .^.j.-...!G..e..    Start Time: 1557485338    Timeout   : 7200 (sec)    Verify return code: 0 (ok)---

证书透明度

通过证书透明度机制,CA 机构、服务器实体、客户端能够监控、审计证书的签发、使用,确保证书是被正确使用的。

查看 github 的 SCT:

$ openssl x509 -in github.cer -noout -text

在线查看支持 OCSP 封套的网站:

$ openssl s_client -connect www.example.com:443 -status -tlsextdebug < /dev/null 2>&1

创建私有证书颁发机构

运行私有CA的最大挑战

如何保证基础结构的安全?

  1. 根密钥必须离线保存。
  2. CRL 和 OSCP 响应程序证书必须定期进行更新,而这会要求根密钥保持联机。

创建全新 CA 的步骤

创建全新 CA 的步骤:

  1. 根 CA 配置;
  2. 创建根 CA 的目录结构和初始化密钥文件;
  3. 生成根 CA 的密钥和证书;
# CA 中心生成自身私钥,为了保证CA机构私钥的安全,需要把私钥文件权限设置为077root@ip-172-31-8-201:/opt/openssl# (umask 077; openssl genrsa -out private/cakey.pem 2048)Generating RSA private key, 2048 bit long modulus...............+++...............................................................+++e is 65537 (0x10001)# CA 签发自身公钥root@ip-172-31-8-201:/opt/openssl# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365You are about to be asked to enter information that will be incorporatedinto your certificate request.What you are about to enter is what is called a Distinguished Name or a DN.There are quite a few fields but you can leave some blankFor some fields there will be a default value,If you enter '.', the field will be left blank.-----Country Name (2 letter code) [AU]:CNState or Province Name (full name) [Some-State]:ShanghaiLocality Name (eg, city) []:ShanghaiOrganization Name (eg, company) [Internet Widgits Pty Ltd]:shanghai Clumsiest Information Co., Ltd.Organizational Unit Name (eg, section) []:Development TeamCommon Name (e.g. server FQDN or YOUR name) []:arlingbc.comEmail Address []:clumsiest@outlook.com# 创建数据库文件及证书序列文件root@ip-172-31-8-201:/opt/openssl# ls -ltotal 52drwxr-xr-x 2 root root  4096 Jun 15 08:08 bin-rw-r--r-- 1 root root  1558 Aug 24 03:21 cacert.pem # CA 自身证书文件drwxr-xr-x 2 root root  4096 Jun 15 09:24 certs      # 客户端证书存放目录drwxr-xr-x 2 root root  4096 Aug 24 05:54 crl        # CA 吊销的客户端证书存放目录*drwxr-xr-x 3 root root  4096 Jun 15 08:08 include-rw-r--r-- 1 root root     0 Aug 24 05:56 index.txt  # 存放客户端证书信息*drwxr-xr-x 4 root root  4096 Jun 15 08:08 libdrwxr-xr-x 6 root root  4096 Jun 15 08:08 mandrwxr-xr-x 2 root root  4096 Jun 15 08:08 miscdrwxr-xr-x 2 root root  4096 Aug 24 05:55 newcerts   # 生成新证书存放目录*-rw-r--r-- 1 root root 10835 Jun 15 08:08 openssl.cnfdrwxr-xr-x 2 root root  4096 Aug 24 03:11 private    # 存放 CA 自身私钥的目录-rw-r--r-- 1 root root     0 Aug 24 05:57 serial     # 客户端证书编号(编号可以自定义),用于识别客户端证书*

附:数字证书格式

RFC 3280 规定了 X.509 数字证书的基本格式

X.509 数字证书结构

X.509 证书域组成

分类标识符说明
证书内容(待签名)tbsCertificate包含持有者公钥、持有者信息、签发者信息等
签名算法signatureAlgorithm包含摘要算法和公钥算法
签名值signatureValue使用签名算法,对证书内容 tbsCertificate 进行签名后的结果

X.509 证书内容

分类标识符说明
版本号version用于区分证书格式版本,最新版本为 v3,缺省值为 v1
序列号serialNumber证书唯一标识
签名算法signature必须与证书域名中的签名算法相同
证书签发者issure用于区分证书签发者,包含证书签发者身份信息
证书有效期validity由生效日期和失效日期组成
证书持有者subject用于区分证书持有者,包含证书持有者身份信息
证书持有者公钥subjectPublicKeyInfo包含证书持有者公钥信息
证书签发者IDissuerUniqueID表示证书签发者唯一标识
证书持有者IDsubjectUniqueID表示证书持有者唯一标识
扩展项extension包含其他可扩展信息

issure 和 subject 包含的主要属性类型

分类OID说明
countryid-at 6国家,C
organizationid-at10单位,O
organizational-unitid-at 11部门,OU
distinguished name qualifierid-at 46DN 限定符
state or province nameid-at 8省份或州,ST
common nameid-at 3通用名称,CN
serial numberid-at 5序列号,SN
localityid-at 7城市,L
domain component域名组件,等同于 DNS,DC
titleid-at 12头衔
surnameid-at 4
given nameid-at 42
initialsid-at 43首字母缩写
pseudonymid-at 65假名
generation qualifierid-at 44时代限定符,如老、小、第四代等
email addresspkcs-9 1电子邮箱

附:OpenSSL 配置文件

openssl.conf 文件

## OpenSSL example configuration file.# This is mostly being used for generation of certificate requests.## This definition stops the following lines choking if HOME isn't# defined.HOME            = .RANDFILE        = $ENV::HOME/.rnd# Extra OBJECT IDENTIFIER info:#oid_file        = $ENV::HOME/.oidoid_section        = new_oids# To use this configuration file with the "-extfile" option of the# "openssl x509" utility, name here the section containing the# X.509v3 extensions to use:# extensions        =# (Alternatively, use a configuration file that has only# X.509v3 extensions in its main [= default] section.)[ new_oids ]# We can add new OIDs in here for use by 'ca', 'req' and 'ts'.# Add a simple OID like this:# testoid1=1.2.3.4# Or use config file substitution like this:# testoid2=${testoid1}.5.6# Policies used by the TSA examples.tsa_policy1 = 1.2.3.4.1tsa_policy2 = 1.2.3.4.5.6tsa_policy3 = 1.2.3.4.5.7####################################################################[ ca ]default_ca    = CA_default        # The default ca section####################################################################[ CA_default ]dir        = ./demoCA        # Where everything is keptcerts        = $dir/certs        # Where the issued certs are keptcrl_dir        = $dir/crl        # Where the issued crl are keptdatabase    = $dir/index.txt    # database index file.#unique_subject    = no            # Set to 'no' to allow creation of                    # several ctificates with same subject.new_certs_dir    = $dir/newcerts        # default place for new certs.certificate    = $dir/cacert.pem     # The CA certificateserial        = $dir/serial         # The current serial numbercrlnumber    = $dir/crlnumber    # the current crl number                    # must be commented out to leave a V1 CRLcrl        = $dir/crl.pem         # The current CRLprivate_key    = $dir/private/cakey.pem# The private keyRANDFILE    = $dir/private/.rand    # private random number filex509_extensions    = usr_cert        # The extentions to add to the cert# Comment out the following two lines for the "traditional"# (and highly broken) format.name_opt     = ca_default        # Subject Name optionscert_opt     = ca_default        # Certificate field options# Extension copying option: use with caution.# copy_extensions = copy# Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs# so this is commented out by default to leave a V1 CRL.# crlnumber must also be commented out to leave a V1 CRL.# crl_extensions    = crl_extdefault_days    = 365            # how long to certify fordefault_crl_days= 30            # how long before next CRLdefault_md    = default        # use public key default MDpreserve    = no            # keep passed DN ordering# A few difference way of specifying how similar the request should look# For type CA, the listed attributes must be the same, and the optional# and supplied fields are just that :-)policy        = policy_match# For the CA policy[ policy_match ]countryName        = matchstateOrProvinceName    = matchorganizationName    = matchorganizationalUnitName    = optionalcommonName        = suppliedemailAddress        = optional# For the 'anything' policy# At this point in time, you must list all acceptable 'object'# types.[ policy_anything ]countryName        = optionalstateOrProvinceName    = optionallocalityName        = optionalorganizationName    = optionalorganizationalUnitName    = optionalcommonName        = suppliedemailAddress        = optional####################################################################[ req ]default_bits        = 2048default_keyfile     = privkey.pemdistinguished_name    = req_distinguished_nameattributes        = req_attributesx509_extensions    = v3_ca    # The extentions to add to the self signed cert# Passwords for private keys if not present they will be prompted for# input_password = secret# output_password = secret# This sets a mask for permitted string types. There are several options.# default: PrintableString, T61String, BMPString.# pkix     : PrintableString, BMPString (PKIX recommendation before 2004)# utf8only: only UTF8Strings (PKIX recommendation after 2004).# nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings).# MASK:XXXX a literal mask value.# WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings.string_mask = utf8only# req_extensions = v3_req # The extensions to add to a certificate request[ req_distinguished_name ]countryName            = Country Name (2 letter code)countryName_default        = AUcountryName_min            = 2countryName_max            = 2stateOrProvinceName        = State or Province Name (full name)stateOrProvinceName_default    = Some-StatelocalityName            = Locality Name (eg, city)0.organizationName        = Organization Name (eg, company)0.organizationName_default    = Internet Widgits Pty Ltd# we can do this but it is not needed normally :-)#1.organizationName        = Second Organization Name (eg, company)#1.organizationName_default    = World Wide Web Pty LtdorganizationalUnitName        = Organizational Unit Name (eg, section)#organizationalUnitName_default    =commonName            = Common Name (e.g. server FQDN or YOUR name)commonName_max            = 64emailAddress            = Email AddressemailAddress_max        = 64# SET-ex3            = SET extension number 3[ req_attributes ]challengePassword        = A challenge passwordchallengePassword_min        = 4challengePassword_max        = 20unstructuredName        = An optional company name[ usr_cert ]# These extensions are added when 'ca' signs a request.# This goes against PKIX guidelines but some CAs do it and some software# requires this to avoid interpreting an end user certificate as a CA.basicConstraints=CA:FALSE# Here are some examples of the usage of nsCertType. If it is omitted# the certificate can be used for anything *except* object signing.# This is OK for an SSL server.# nsCertType            = server# For an object signing certificate this would be used.# nsCertType = objsign# For normal client use this is typical# nsCertType = client, email# and for everything including object signing:# nsCertType = client, email, objsign# This is typical in keyUsage for a client certificate.# keyUsage = nonRepudiation, digitalSignature, keyEncipherment# This will be displayed in Netscape's comment listbox.nsComment            = "OpenSSL Generated Certificate"# PKIX recommendations harmless if included in all certificates.subjectKeyIdentifier=hashauthorityKeyIdentifier=keyid,issuer# This stuff is for subjectAltName and issuerAltname.# Import the email address.# subjectAltName=email:copy# An alternative to produce certificates that aren't# deprecated according to PKIX.# subjectAltName=email:move# Copy subject details# issuerAltName=issuer:copy#nsCaRevocationUrl        = http://www.domain.dom/ca-crl.pem#nsBaseUrl#nsRevocationUrl#nsRenewalUrl#nsCaPolicyUrl#nsSslServerName# This is required for TSA certificates.# extendedKeyUsage = critical,timeStamping[ v3_req ]# Extensions to add to a certificate requestbasicConstraints = CA:FALSEkeyUsage = nonRepudiation, digitalSignature, keyEncipherment[ v3_ca ]# Extensions for a typical CA# PKIX recommendation.subjectKeyIdentifier=hashauthorityKeyIdentifier=keyid:always,issuer# This is what PKIX recommends but some broken software chokes on critical# extensions.#basicConstraints = critical,CA:true# So we do this instead.basicConstraints = CA:true# Key usage: this is typical for a CA certificate. However since it will# prevent it being used as an test self-signed certificate it is best# left out by default.# keyUsage = cRLSign, keyCertSign# Some might want this also# nsCertType = sslCA, emailCA# Include email address in subject alt name: another PKIX recommendation# subjectAltName=email:copy# Copy issuer details# issuerAltName=issuer:copy# DER hex encoding of an extension: beware experts only!# obj=DER:02:03# Where 'obj' is a standard or added object# You can even override a supported extension:# basicConstraints= critical, DER:30:03:01:01:FF[ crl_ext ]# CRL extensions.# Only issuerAltName and authorityKeyIdentifier make any sense in a CRL.# issuerAltName=issuer:copyauthorityKeyIdentifier=keyid:always[ proxy_cert_ext ]# These extensions should be added when creating a proxy certificate# This goes against PKIX guidelines but some CAs do it and some software# requires this to avoid interpreting an end user certificate as a CA.basicConstraints=CA:FALSE# Here are some examples of the usage of nsCertType. If it is omitted# the certificate can be used for anything *except* object signing.# This is OK for an SSL server.# nsCertType            = server# For an object signing certificate this would be used.# nsCertType = objsign# For normal client use this is typical# nsCertType = client, email# and for everything including object signing:# nsCertType = client, email, objsign# This is typical in keyUsage for a client certificate.# keyUsage = nonRepudiation, digitalSignature, keyEncipherment# This will be displayed in Netscape's comment listbox.nsComment            = "OpenSSL Generated Certificate"# PKIX recommendations harmless if included in all certificates.subjectKeyIdentifier=hashauthorityKeyIdentifier=keyid,issuer# This stuff is for subjectAltName and issuerAltname.# Import the email address.# subjectAltName=email:copy# An alternative to produce certificates that aren't# deprecated according to PKIX.# subjectAltName=email:move# Copy subject details# issuerAltName=issuer:copy#nsCaRevocationUrl        = http://www.domain.dom/ca-crl.pem#nsBaseUrl#nsRevocationUrl#nsRenewalUrl#nsCaPolicyUrl#nsSslServerName# This really needs to be in place for it to be a proxy certificate.proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo####################################################################[ tsa ]default_tsa = tsa_config1    # the default TSA section[ tsa_config1 ]# These are used by the TSA reply generation only.dir        = ./demoCA        # TSA root directoryserial        = $dir/tsaserial    # The current serial number (mandatory)crypto_device    = builtin        # OpenSSL engine to use for signingsigner_cert    = $dir/tsacert.pem     # The TSA signing certificate                    # (optional)certs        = $dir/cacert.pem    # Certificate chain to include in reply                    # (optional)signer_key    = $dir/private/tsakey.pem # The TSA private key (optional)default_policy    = tsa_policy1        # Policy if request did not specify it                    # (optional)other_policies    = tsa_policy2, tsa_policy3    # acceptable policies (optional)digests        = md5, sha1        # Acceptable message digests (mandatory)accuracy    = secs:1, millisecs:500, microsecs:100    # (optional)clock_precision_digits  = 0    # number of digits after dot. (optional)ordering        = yes    # Is ordering defined for timestamps?                # (optional, default: no)tsa_name        = yes    # Must the TSA name be included in the reply?                # (optional, default: no)ess_cert_id_chain    = no    # Must the ESS cert id chain be included?                # (optional, default: no)

root-ca.conf 文件

# 配置文件第一部分包括了CA的名称、基础URL和CA可分辨名称等基本信息。[default]name                    = root-cadomain_suffix           = example.comaia_url                 = http://$name.$domain_suffix/$name.crtcrl_url                 = http://$name.$domain_suffix/$name.crlocsp_url                = http://ocsp.$name.$domain_suffix:9080default_ca              = ca_defaultname_opt                = utf8,esc_ctrl,multiline,lname,align[ca_dn]countryName             = "GB"organizationName        = "Example"commonName              = "Root CA"# 第二部分直接控制了CA的操作。[ca_default]home                    = .database                = $home/db/indexserial                  = $home/db/serialcrlnumber               = $home/db/crlnumbercertificate             = $home/$name.crtprivate_key             = $home/private/$name.keyRANDFILE                = $home/private/randomnew_certs_dir           = $home/certsunique_subject          = nocopy_extensions         = nonedefault_days            = 3650 # 有效期10年default_crl_days        = 365default_md              = sha256 # 使用SHA256作为签名算法policy                  = policy_c_o_match[policy_c_o_match] # 默认策略,限制了这张CA签发的证书的国家名和组织名会与CA本身一样。countryName             = matchstateOrProvinceName     = optionalorganizationName        = matchorganizationalUnitName  = optionalcommonName              = suppliedemailAddress            = optional# 第三部包含了req命令的配置,req命令只会在创建自签发根证书的时候用到一次。最重要的部分是扩展:[req]default_bits            = 4096encrypt_key             = yesdefault_md              = sha256utf8                    = yesstring_mask             = utf8onlyprompt                  = nodistinguished_name      = ca_dnreq_extensions          = ca_ext[ca_ext]# 基本限制(basicContraints)扩展表明这个证书是一张CAbasicConstraints        = critical,CA:true# 密钥用法(keyUsage) 扩展用来说明这个CA的用处keyUsage                = critical,keyCertSign,cRLSignsubjectKeyIdentifier    = hash# 配置的第四部分包括了根CA创建证书所需要的信息。# 因为基本限制(basicContraints)扩展的设置,所有的证书都将成为CA,但是我们需要把pathlen设置为0,表示这些CA无法再签发新的CA了。[sub_ca_ext]authorityInfoAccess     = @issuer_infoauthorityKeyIdentifier  = keyid:alwaysbasicConstraints        = critical,CA:true,pathlen:0crlDistributionPoints   = @crl_info# 第一,扩展密钥用法(extendedKeyUsage)扩展限制了只能进行客户端验证 (clientAuth)和服务器验证(serverAuth),也就是TLS的客户端和服务器验证。extendedKeyUsage        = clientAuth,serverAuthkeyUsage                = critical,keyCertSign,cRLSign# 第二,名称限制(nameContraints)扩展限制了允许签发的域名只有example.com和example.org。nameConstraints         = @name_constraintssubjectKeyIdentifier    = hash[crl_info]URI.0                   = $crl_url[issuer_info]caIssuers;URI.0         = $aia_urlOCSP;URI.0              = $ocsp_url[name_constraints]permitted;DNS.0=example.compermitted;DNS.1=example.orgexcluded;IP.0=0.0.0.0/0.0.0.0excluded;IP.1=0:0:0:0:0:0:0:0/0:0:0:0:0:0:0:0# 最后两部分的配置表示有了这个扩展的证书可以对OCSP响应进行签名。为了能够运行OCSP 响应程序,我们生成一个特别的证书,并且将OCSP的签名能力赋予这张证书。从扩展可以看出 这张证书不是一个CA[ocsp_ext]authorityKeyIdentifier  = keyid:alwaysbasicConstraints        = critical,CA:falseextendedKeyUsage        = OCSPSigningnoCheck                 = yeskeyUsage                = critical,digitalSignaturesubjectKeyIdentifier    = hash

参考

  • 《深入浅出 HTTPS》
  • 《HTTPS 权威指南:在服务器和 Web 应用上部署 SSL/TLS 和 PKI》
  • OpenSSL Cookbook
  • OpenSSL 隐形战友
  • 知乎:为什么 SSL 证书那么贵?
  • 知乎:SSL 证书服务,大家用哪家的?
  • openSSL 命令、PKI、CA、SSL 证书原理
  • OpenSSL 中文手册 之一 OpenSSL 简介-证书
  • Let's Encrypt,免费好用的 HTTPS 证书
  • 主流浏览器直接信任 Let’s Encrypt 根证书,宣告他成为顶级 CA