Contents

使用OpenSSL提取证书信息

1. 概述

在本教程中,我们将学习如何使用openssl工具的 x509 子命令从 X.509 公钥证书中提取信息。

2. 什么是 X.509 公钥证书?

在 TLS 和 SSL 加密协议中,公钥证书是网站提供给最终用户的电子证书。通过证书,网站可以向访问者证明其合法性。然后,访问者可以放心地与网站互动。

X.509 是定义公钥证书的标准之一。它是互联网上最常用的一种。

3. X.509 证书包含什么?

让我们看一个示例 X.509 证书:

Certificate:
    Data:
        Serial Number:
            24:4e:52:d9:6b:55:1f:96:0a:00:00:00:00:f2:ba:f4
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
        Validity
            Not Before: Jul 12 01:35:31 2021 GMT
            Not After : Oct  4 01:35:30 2021 GMT
        Subject: CN = *.google.com
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Alternative Name:
                DNS:*.google.com, DNS:*.appengine.google.com, DNS:*.bdn.dev, 
                ...(truncated)
    Signature Algorithm: sha256WithRSAEncryption
         c1:0b:9e:6b:58:ea:5f:31:c8:25:1a:49:b6:fc:dd:a6:46:73:
         ...(truncated)

上面的证书片段适用于google.com。它包含各种信息。

首先,**每个证书都包含一个序列号。**这是颁发者在签署证书时给出的值。

**证书的颁发者在字段Issuer下定义。**对于此特定证书,颁发者属于位于美国的 Google Trust Services LLC 组织。此外,发行人的通用名称为GTS CA 1C3

接下来,Validity字段定义了证书的有效期。特别是,证书仅在 Not Before和 Not After定义的期限内有效。

在 Subject字段中,我们可以看到该证书的通用名称为 *.google.com。这是一个通配符通用名称,它允许google.com的所有子域使用相同的证书来标识自己。此外,** Subject公钥信息字段指定此证书的公钥**。在同一字段下,证书还定义了公钥的算法类型以及必要的参数。

**在X509v3 扩展字段中,我们可以找到 X.509 证书标准版本 3 上的几个扩展属性。**例如,X509v3 主题备用名称字段定义使用相同证书进行身份验证的其他域。换言之,此证书也适用于*.cloud.google.com、*.appengine.google.com*等。

最后,我们可以看到一个 Signature Algorithm 字段,后跟一个十六进制块。此字段指定进行签名时使用的算法。在这种情况下,它是sha256WithRSAEncryption。此外,十六进制块是发行者签名的签名。签名的作用是确保证书上的信息在经过证书颁发机构验证后没有被篡改

4. openssl工具

openssl 工具是一个实现 SSL/TLS 网络协议的加密库。 它包含满足任何 SSL/TLS 通信需求的不同子命令。

例如,s_client 命令是 SSL/TLS 客户端的实现。除此之外,x509 子命令提供了多种使用 X.509 证书的功能

4.1. 安装

大多数 Linux 发行版都包含openssl命令。如果它不可用,我们可以使用包管理器安装它。

对于基于 Debian 的 Linux,我们可以使用apt-get 包管理器:

$ sudo apt-get update
$ sudo apt-get install -y openssl

对于基于 RHEL 的 Linux,我们可以使用yum 包管理器:

$ sudo yum update
$ sudo yum install -y openssl

对于 Alpine Linux,我们可以使用*apk *包管理器:

$ sudo apk add openssl

我们可以运行openssl子命令版本来确认安装成功:

$ openssl version
OpenSSL 1.1.1k  25 Mar 2021

5. 获取 X.509 公钥证书文件

假设我们要获取 google.com 的公钥证书文件 。我们可以使用openssls_client和 x509子命令来做到这一点:

$ openssl s_client -connect google.com:443 -showcerts </dev/null | openssl x509 -outform pem > googlecert.pem

使用s_client连接到主机 google.com 的端口 443 会启动 TLS 握手。

-showcerts选项表示我们要将证书打印到标准输出*。在我们获得证书后,将/dev/null*重定向到标准输入会终止连接。

然后,我们将证书与*-outform选项一起通过管道传输到x509子命令,以将 其编码为 PEM 格式。最后,我们将证书文件保存为googlecert.pem*。

6. 解码整个证书

PEM 格式的证书是 base64 编码的。例如,这是我们之前获得的googlecert.pem文件:

## $ cat googlecert.pem
MIINUDCCDDigAwIBAgIQJE5S2WtVH5YKAAAAAPK69DANBgkqhkiG9w0BAQsFADBG
MQswCQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExM
## ...(truncated)

要将整个证书解码为纯文本,我们使用带有-text选项的x509*命令*:

$ openssl x509 -in googlecert.pem -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            24:4e:52:d9:6b:55:1f:96:0a:00:00:00:00:f2:ba:f4
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, O = Google Trust Services LLC, CN = GTS CA 1C3
        Validity
            Not Before: Jul 12 01:35:31 2021 GMT
            Not After : Oct  4 01:35:30 2021 GMT
        ...(truncated)

首先,  -in选项指定要解码的证书文件。然后,-noout选项会阻止该命令的任何输出。如果没有-noout*选项,该命令将默认返回 base64 编码的证书*。

最后,我们指定*-text*选项以纯文本形式打印整个证书。

7. 从证书中提取特定信息

使用 x509子命令,我们可以从证书中提取不同的字段。

7.1. 提取主题

x509 子命令中的 -subject 选项允许我们提取证书的主题让我们使用x509从**googlecert.pem文件中提取主题信息:

$ openssl x509 -in googlecert.pem -noout -subject
subject=CN = *.google.com

7.2. 提取发行人

我们可以使用-issuer选项从证书中提取颁发者信息。 例如,要从 googlecert.pem文件中提取颁发者信息:

$ openssl x509 -in googlecert.pem -noout -issuer
issuer=C = US, O = Google Trust Services LLC, CN = GTS CA 1C3

7.3. 提取扩展字段

要获取 X.509 公钥证书中的扩展字段,我们可以使用-ext*选项*。 例如,指定 -ext选项后跟subjectAltName将为我们提供证书中的主题替代名称:

$ openssl x509 -in googlecert.pem -noout -ext subjectAltName
X509v3 Subject Alternative Name:
    DNS:*.google.com, DNS:*.appengine.google.com, DNS:*.bdn.dev, DNS:*.cloud.google.com, DNS:*.crowdsource.google.com, DNS:*.datacompute.google.com, ...(truncated)

同样,我们可以使用相同的选项来使用keyUsage参数获取密钥使用字段:

$ openssl x509 -in googlecert.pem -noout -ext keyUsage
X509v3 Key Usage: critical
    Digital Signature

7.4. 格式化名称输出

对于颁发者和主题等输出,我们可以使用 -nameopt选项另外指定显示格式。

例如,我们可以使用*-nameopt选项后跟sep_multiline*运算符将发行者信息分成多行:

$ openssl x509 -in googlecert.pem -noout -issuer -nameopt sep_multiline
issuer=
    C=US
    O=Google Trust Services LLC
    CN=GTS CA 1C3

我们还可以通过将lname运算符传递给 -nameopt来显示长字段名称而不是缩写:

$ openssl x509 -in googlecert.pem -noout -issuer -nameopt lname
issuer=countryName=US, organizationName=Google Trust Services LLC, commonName=GTS CA 1C3

最后, 可以多次指定*-nameopt选项以组合不同操作员的行为。例如,我们可以结合lname*和 sep_multiline运算符:

$ openssl x509 -in googlecert.pem -noout -issuer -nameopt lname -nameopt sep_multiline
issuer=
    countryName=US
    organizationName=Google Trust Services LLC
    commonName=GTS CA 1C3

openssl命令的手册页 提供了格式参数的完整列表。

7.5.提取开始日期和到期日期

每个证书都指定了开始日期和到期日期。这两个日期很重要,因为证书仅在此期间有效。

要获取这两个日期,我们可以指定-dates*选项:*

$ openssl x509 -in googlecert.pem -noout -dates
notBefore=Jul 12 01:35:31 2021 GMT
notAfter=Oct  4 01:35:30 2021 GMT

或者,我们可以使用*-startdate*选项仅打印开始日期:

$ openssl x509 -in googlecert.pem -noout -startdate
notBefore=Jul 12 01:35:31 2021 GMT

同样,使用 -enddate选项,我们可以获得证书的到期日期:

$ openssl x509 -in googlecert.pem -noout -enddate
notAfter=Oct  4 01:35:30 2021 GMT

7.6. 提取其他信息

每个证书都有一个指纹,用于唯一标识一个特定的证书。

要提取指纹,我们可以运行带有 -fingerprint选项的x509子命令:

$ openssl x509 -in googlecert.pem -noout -fingerprint
SHA1 Fingerprint=5E:0B:46:9E:55:07:70:5A:C3:40:12:66:06:89:9A:92:E8:C2:15:E4

除此之外,我们可以使用-serial*选项*获取证书的序列号。例如:

$ openssl x509 -in googlecert.pem -noout -serial
serial=244E52D96B551F960A00000000F2BAF4

最后,我们可以使用***-pubkey*选项提取证书的**公钥:

## $ openssl x509 -in googlecert.pem -noout -pubkey 
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAESDHX4ovWPfaIWPNZPCKJGTx7QjE5 
## 0gifWTUyw+t7DkNvq+2nErrpWocdifYDOoX8E+63JdEFlrRwhu4jXZheYA== 

7.7. 检查证书是否即将过期

使用x509子命令的-checkend*选项,我们可以快速检查证书是否即将过期。*

该选项采用附加参数n,其单位为秒。一般来说:

$ openssl x509 -in <certificate-filename> -noout -checkend n

上面的命令将检查证书是否在接下来的 n秒内到期。如果是,该命令将导致 1 返回状态代码。如果给定的证书在接下来的n 秒内没有过期,该命令将返回 0 状态代码。此外,该命令将返回一条消息,指示证书的到期状态。 例如,要确定证书是否在接下来的 60 秒内到期:

$ openssl x509 -in googlecert.pem -noout -checkend 60
Certificate will not expire
$ echo $?
0

上面的命令返回状态码 0,因为证书在接下来的 60 秒内没有过期。

现在让我们检查下同一个证书是否会在接下来的 20 周内过期:

$ openssl x509 -in googlecert.pem -noout -checkend 12096000
Certificate will expire
$ echo $?
1

由于证书将在接下来的 20 周内到期,我们得到的返回状态代码为 1。