如何使用 OpenSSL 查看 SSL/TLS 证书详情 – wiki基地


深入解析:使用 OpenSSL 详细查看 SSL/TLS 证书信息

在当今高度互联的数字世界中,网络安全是基石。SSL/TLS(安全套接层/传输层安全)协议是保护网络通信、确保数据传输机密性和完整性的核心技术。而 SSL/TLS 证书,则是在这个信任体系中扮演着数字身份证明的关键角色。无论是网站管理员、网络工程师、安全专家还是开发人员,经常需要深入了解这些证书的具体内容,以进行故障排查、安全审计或配置验证。OpenSSL,作为一个强大的开源密码学工具包,提供了丰富的功能,其中就包括检查和解析 SSL/TLS 证书的详细信息。本文将深入探讨如何利用 OpenSSL 这个瑞士军刀,从不同角度、不同场景下查看和分析 SSL/TLS 证书的方方面面。

一、 理解 SSL/TLS 证书及其重要性

在我们深入 OpenSSL 的命令之前,有必要先回顾一下 SSL/TLS 证书的基本概念及其为何如此重要。

什么是 SSL/TLS 证书?

想象一下现实世界中的护照或身份证,它们用于证明一个人的身份。SSL/TLS 证书在数字世界中扮演着类似的角色。它是一个由受信任的第三方机构——证书颁发机构(Certificate Authority, CA)签发的数字文件。这个文件包含以下关键信息:

  1. 主体(Subject)信息: 证书持有者的身份信息,例如网站的域名(Common Name, CN)、组织名称(Organization, O)、组织单位(Organizational Unit, OU)、地点(Locality, L)、州/省(State/Province, ST)和国家(Country, C)等。
  2. 颁发者(Issuer)信息: 签发该证书的 CA 的身份信息。对于自签名证书,颁发者和主体是相同的。
  3. 公钥(Public Key): 与证书持有者私钥配对的公钥。该公钥用于加密发送给服务器的数据(例如在密钥交换过程中)或验证服务器的数字签名。
  4. 有效期(Validity Period): 证书生效的起始日期(Not Before)和失效日期(Not After)。过期的证书通常不被信任。
  5. 序列号(Serial Number): 由 CA 分配的唯一标识符,用于追踪和管理证书。
  6. 签名算法(Signature Algorithm): CA 用于对证书进行数字签名的算法(例如 SHA256withRSA)。浏览器或客户端使用 CA 的公钥来验证此签名,确保证书未被篡改且确实由该 CA 颁发。
  7. 指纹/摘要(Thumbprint/Digest): 证书内容的哈希值(如 SHA-1, SHA-256),用于快速比较和识别证书。
  8. 密钥用法(Key Usage)和扩展密钥用法(Extended Key Usage, EKU): 指定证书及其关联密钥的预期用途,例如数字签名、密钥加密、服务器认证、客户端认证等。
  9. 主题备用名称(Subject Alternative Name, SAN): 这是现代证书中极其重要的一个扩展字段。它允许一个证书保护多个域名、子域名、IP 地址甚至电子邮件地址。现代浏览器主要依赖 SAN 字段来验证域名匹配,而不是仅仅依赖 CN。
  10. 证书链(Certificate Chain)信息(可选): 指向颁发该证书的中间 CA 证书的链接信息(Authority Information Access, AIA),帮助客户端构建完整的信任链。

为什么需要查看证书详情?

查看证书详情的原因多种多样,包括但不限于:

  • 故障排查: 当浏览器或应用程序报告 SSL/TLS 错误(如证书过期、名称不匹配、不受信任的颁发者)时,检查证书细节是定位问题的关键步骤。
  • 安全验证: 确认网站或服务的身份是否与其声称的一致,检查证书是否由可信的 CA 颁发,有效期是否正常。
  • 配置确认: 验证服务器上部署的证书是否正确,是否包含了所有必要的域名(特别是检查 SAN 字段),密钥用法是否符合预期。
  • 安全审计: 检查证书使用的签名算法、密钥长度是否符合当前的安全标准(例如,避免使用过时的 SHA-1 签名或 RSA 1024 位密钥)。
  • 了解证书链: 查看完整的证书链,了解信任的传递路径,排查中间证书问题。
  • 开发与测试: 开发人员在集成需要 mTLS(双向 TLS 认证)的应用或处理证书相关逻辑时,需要检查客户端或服务器证书的详细属性。

二、 OpenSSL 简介

OpenSSL 是一个功能强大的、商业级的、功能齐全的开源工具包,实现了 SSL 和 TLS 协议以及一个通用的密码学库。它广泛应用于各种网络服务器(如 Apache, Nginx)、操作系统和应用程序中。其命令行工具 openssl 提供了丰富的功能,包括:

  • 生成密钥对(RSA, ECC 等)
  • 创建证书签名请求(CSR)
  • 签发和管理数字证书(可以搭建小型 CA)
  • 进行加密和解密操作
  • 计算哈希摘要和消息认证码(MAC)
  • 以及我们本文的重点:连接到 SSL/TLS 服务并检查其证书,或解析本地证书文件。

在大多数 Linux 发行版和 macOS 上,OpenSSL 通常是预装的。在 Windows 上,你可能需要单独下载并安装它(例如,从官方推荐的第三方构建或通过包管理器如 Chocolatey)。你可以通过在终端或命令提示符中运行 openssl version 来检查是否已安装以及其版本。

三、 使用 OpenSSL 查看远程服务器的 SSL/TLS 证书

最常见的需求是检查一个正在运行的 Web 服务器(或其他启用 TLS 的服务)所使用的证书。这可以通过 openssl s_client 命令来实现。s_client 是一个通用的 SSL/TLS 客户端,可以连接到远程服务器,并显示连接过程中的详细信息,包括服务器发送的证书。

基础用法

最基本的命令格式是:

bash
openssl s_client -connect <hostname>:<port>

  • <hostname>: 你想要连接的服务器的域名或 IP 地址。
  • <port>: 服务器监听 SSL/TLS 连接的端口。对于 HTTPS,默认端口是 443。对于其他服务(如 SMTPS, IMAPS, POP3S),端口会有所不同。

示例:查看 www.google.com 的证书

bash
openssl s_client -connect www.google.com:443

执行这个命令后,OpenSSL 会尝试与 www.google.com 的 443 端口建立一个 TLS 连接。输出会相当冗长,包含以下几个主要部分:

  1. 连接信息(CONNECTED/DEPTH/VERIFY): 显示连接建立的状态,以及证书链验证的过程和结果。verify return:1 通常表示验证成功(基于 OpenSSL 默认的信任库,这可能不完整或与浏览器不同)。
  2. 证书链(Certificate chain): 服务器通常会发送整个证书链,从服务器证书(深度 0)开始,向上到中间 CA 证书,直至根 CA(根 CA 通常不由服务器发送,客户端本地存储)。每个证书都以 -----BEGIN CERTIFICATE----------END CERTIFICATE----- 包裹。
  3. 服务器证书详情(Server certificate): 这是我们最关心的部分。s_client 会直接显示服务器证书(链中的第一个证书)的一些关键信息,如 Subject 和 Issuer。
  4. SSL 会话参数: 包括协商使用的 TLS 协议版本(如 TLSv1.3)、密码套件(Cipher)、会话 ID、密钥交换信息等。
  5. (可能)服务器响应或等待输入: 连接建立后,s_client 可能会等待你输入数据发送给服务器,或者显示服务器发送的一些初始信息。你可以按 Ctrl+C 退出。

专注于证书文本输出

s_client 的原始输出混合了连接信息和证书文本。如果你只想获得服务器证书的详细文本解析,可以将 s_client 的输出通过管道传递给 openssl x509 命令进行处理。

首先,我们需要确保 s_client 在建立连接后立即关闭,而不是等待输入。这可以通过重定向标准输入或使用 -ign_eof 选项(有时不完全可靠)来实现。一个常用的技巧是使用 echo |</dev/null

“`bash
echo | openssl s_client -connect www.google.com:443

或者

openssl s_client -connect www.google.com:443 </dev/null
“`

为了只获取证书内容并进行解析,我们可以这样做:

bash
echo | openssl s_client -connect www.google.com:443 -showcerts 2>/dev/null | openssl x509 -text -noout

让我们分解这个命令:

  • echo | openssl s_client -connect www.google.com:443: 连接服务器并获取输出,echo | 使其自动关闭。
  • -showcerts: 这个选项让 s_client 输出服务器发送的整个证书链,而不仅仅是摘要信息。
  • 2>/dev/null: 重定向标准错误输出到空设备,这会隐藏连接过程中的调试信息和错误消息,使输出更干净,只留下证书内容。
  • |: 管道符,将前一个命令的标准输出传递给后一个命令的标准输入。
  • openssl x509: 调用 OpenSSL 的 X.509 证书处理工具。
  • -text: 指示 x509 工具将输入的证书(默认期望是 PEM 格式)解析成人类可读的文本格式。
  • -noout: 指示 x509 工具不要输出原始的 Base64 编码的证书内容,只输出解析后的文本。

注意: 上述命令会解析管道传过来的 第一个 证书。由于 -showcerts 会输出整个链,这通常就是服务器证书。如果你想查看链中的特定证书(例如第一个中间 CA 证书),你需要先将证书链保存到文件,然后分别提取和解析。

处理 SNI(服务器名称指示)

现代服务器通常在同一 IP 地址上托管多个 HTTPS 网站,它们依赖客户端在 TLS 握手初期通过 SNI 扩展告知要访问的域名。如果服务器需要 SNI,而 s_client 没有提供,服务器可能会返回一个默认的、错误的证书,或者干脆拒绝连接。使用 -servername 选项来指定 SNI:

bash
echo | openssl s_client -connect <IP_ADDRESS>:<PORT> -servername <hostname> 2>/dev/null | openssl x509 -text -noout

例如,假设 example.comanother-example.com 托管在同一 IP 192.0.2.10 上:

“`bash

请求 example.com 的证书

echo | openssl s_client -connect 192.0.2.10:443 -servername example.com 2>/dev/null | openssl x509 -text -noout

请求 another-example.com 的证书

echo | openssl s_client -connect 192.0.2.10:443 -servername another-example.com 2>/dev/null | openssl x509 -text -noout
“`

指定 TLS/SSL 协议版本

有时,你可能想测试服务器是否支持特定的 TLS 版本,或者强制使用某个版本进行连接。可以使用以下选项:
* -tls1_3, -tls1_2, -tls1_1, -tls1
* -no_tls1_3, -no_tls1_2, -no_tls1_1, -no_tls1, -no_ssl3 (禁用特定版本)

例如,强制使用 TLS 1.2 连接:

bash
openssl s_client -connect www.google.com:443 -tls1_2

提取证书到文件

如果你想把服务器证书保存到一个文件中以便后续分析,可以这样做:

bash
openssl s_client -showcerts -connect www.google.com:443 </dev/null | \
sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' > google_certs.pem

这个命令:
1. 连接服务器并获取包含所有证书的输出 (-showcerts)。
2. 使用 sed 命令提取所有 -----BEGIN CERTIFICATE----------END CERTIFICATE----- 之间的内容(包括标记本身)。
3. 将提取的证书(可能是整个链)保存到 google_certs.pem 文件中。这个文件是 PEM 格式,可以用文本编辑器打开,或者用下面的 openssl x509 命令进一步处理。

如果你只想保存服务器证书(链中的第一个),可以稍微修改 sed 或使用 awk

“`bash

使用 awk 获取第一个证书

openssl s_client -showcerts -connect www.google.com:443 server_cert.pem
“`

然后,你可以使用 openssl x509 来查看这个保存下来的 server_cert.pem 文件。

四、 使用 OpenSSL 查看本地证书文件

除了查看远程服务器的证书,你可能也需要检查本地存储的证书文件。这些文件可能来自:

  • 你自己生成的证书或 CA。
  • 从 CA 下载的证书文件。
  • 从服务器导出的证书。
  • 应用程序使用的证书。

证书文件常见的格式有 PEM (Base64 ASCII 编码,通常以 .pem, .crt, .cer, .key 结尾) 和 DER (二进制编码,通常以 .der, .cer 结尾)。OpenSSL 的 x509 命令可以处理这两种格式。

查看 PEM 格式证书

PEM 是最常见的格式。使用 openssl x509 命令:

bash
openssl x509 -in certificate.pem -text -noout

  • -in filename: 指定输入的证书文件名。
  • -text: 解析并以人类可读的文本格式显示证书内容。
  • -noout: 禁止输出 Base64 编码的证书本身。

这将输出证书的详细信息,与之前通过管道从 s_client 获取的格式相同。

查看 DER 格式证书

如果你的证书是 DER 格式,需要告诉 OpenSSL 输入的格式:

bash
openssl x509 -in certificate.der -inform DER -text -noout

  • -inform DER: 指定输入文件格式为 DER。

提取特定信息

openssl x509 命令非常灵活,可以只提取你感兴趣的特定信息,而无需显示完整的文本输出。这对于脚本化处理或快速检查很有用。以下是一些常用的选项:

  • 查看主题 (Subject):
    bash
    openssl x509 -in certificate.pem -noout -subject
    # 输出: subject=C = US, ST = California, L = Mountain View, O = Google LLC, CN = www.google.com

  • 查看颁发者 (Issuer):
    bash
    openssl x509 -in certificate.pem -noout -issuer
    # 输出: issuer=C = US, O = Google Trust Services LLC, CN = GTS CA 1C3

  • 查看序列号 (Serial Number):
    bash
    openssl x509 -in certificate.pem -noout -serial
    # 输出: serial=0123456789ABCDEF0123456789ABCDEF

  • 查看有效期 (Validity Dates):
    bash
    openssl x509 -in certificate.pem -noout -dates
    # 输出:
    # notBefore=Jan 1 00:00:00 2023 GMT
    # notAfter=Dec 31 23:59:59 2024 GMT

    或者分开获取:
    bash
    openssl x509 -in certificate.pem -noout -startdate
    openssl x509 -in certificate.pem -noout -enddate

  • 查看指纹 (Fingerprint): 默认是 SHA1,但强烈建议使用 SHA256。
    bash
    openssl x509 -in certificate.pem -noout -fingerprint
    # 输出 SHA1 指纹
    openssl x509 -in certificate.pem -noout -fingerprint -sha256
    # 输出 SHA256 指纹
    openssl x509 -in certificate.pem -noout -fingerprint -md5
    # 输出 MD5 指纹 (不推荐)

  • 查看公钥:
    bash
    openssl x509 -in certificate.pem -noout -pubkey
    # 输出 PEM 格式的公钥

  • 查看证书目的 (Purpose): 检查证书是否适用于特定的用途,例如 SSL 服务器。
    bash
    openssl x509 -in certificate.pem -noout -purpose
    # 输出会列出所有用途,并标明是否满足 (Yes/No)
    # SSL server : Yes
    # SSL client : No
    # ...

  • 查看主题备用名称 (SAN): SAN 信息通常在 -text 输出的 X509v3 extensions: 部分。没有直接的命令只提取 SAN,但可以结合 grepawk
    bash
    openssl x509 -in certificate.pem -noout -text | grep -A 1 'Subject Alternative Name'
    # 或者更精确地提取 DNS 名称:
    openssl x509 -in certificate.pem -noout -text | awk '/X509v3 Subject Alternative Name:/ {getline; print}' | sed 's/DNS://g; s/, /\n/g'

  • 查看签名算法:
    bash
    openssl x509 -in certificate.pem -noout -text | grep "Signature Algorithm"

五、 深入解析证书内容字段

当使用 openssl x509 -text 查看证书时,你会看到很多字段。理解这些字段的含义至关重要:

  • Version: X.509 证书的版本(通常是 3)。
  • Serial Number: CA 分配的唯一编号。
  • Signature Algorithm: CA 签名证书使用的算法(如 sha256WithRSAEncryption)。
  • Issuer: 颁发证书的 CA 的信息(C, ST, L, O, OU, CN)。
  • Validity:
    • Not Before: 证书生效日期。
    • Not After: 证书失效日期。
  • Subject: 证书持有者的信息(C, ST, L, O, OU, CN)。对于网站证书,CN (Common Name) 曾是主要的域名标识,但现在 SAN 更重要。
  • Subject Public Key Info:
    • Public Key Algorithm: 使用的公钥算法(如 rsaEncryption, id-ecPublicKey)。
    • Public-Key: 密钥大小(如 2048 bit, 256 bit for ECC)和公钥本身(通常以十六进制显示)。
  • X509v3 extensions: 这是 V3 证书的关键部分,包含许多重要的扩展信息:
    • X509v3 Basic Constraints: CA:TRUECA:FALSE,表明该证书是否是 CA 证书(能否用于签发其他证书)。Path Length Constraint 限制了其下级 CA 的深度。
    • X509v3 Key Usage: 定义了密钥的基本用途,是位掩码(bitmask),常见的有 Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, Key Agreement, Certificate Sign, CRL Sign
    • X509v3 Extended Key Usage: 更具体地定义了密钥的用途,例如 TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, Email Protection
    • X509v3 Subject Alternative Name (SAN): 极其重要。列出了证书有效的所有标识,如 DNS:example.com, DNS:www.example.com, IP Address:192.0.2.1。浏览器在验证域名时会检查这里。
    • X509v3 Authority Key Identifier (AKI): 包含颁发者证书的公钥标识符,帮助客户端找到正确的颁发者证书来构建信任链。
    • X509v3 Subject Key Identifier (SKI): 该证书自身的公钥标识符,用于被其他证书的 AKI 引用。
    • X509v3 CRL Distribution Points (CDP): 指向证书吊销列表 (CRL) 的 URL,客户端可以下载此列表检查证书是否已被吊销。
    • Authority Information Access (AIA):
      • CA Issuers: 指向颁发者(中间 CA)证书的 URL,客户端可以下载它来补全证书链。
      • OCSP: 指向在线证书状态协议 (OCSP) 响应器的 URL,客户端可以通过 OCSP 查询证书的实时吊销状态。
    • Certificate Policies: 包含了证书符合的策略信息,通常是 OID (对象标识符)。
  • Signature Algorithm: (再次出现) CA 对整个证书内容(包括上述所有字段)进行签名的算法。
  • Signature Value: CA 使用其私钥生成的数字签名,以十六进制显示。

六、 使用 OpenSSL 验证证书

仅仅查看证书内容还不够,有时需要验证证书是否由受信任的 CA 签发,以及证书链是否完整有效。可以使用 openssl verify 命令。

你需要一个包含受信任 CA 根证书和中间证书的“信任锚”文件(通常称为 CA bundle 或 trust store)。

bash
openssl verify -CAfile ca-bundle.pem certificate.pem

  • -CAfile filename: 指定包含信任 CA 证书的 PEM 文件。许多系统(如 Linux)在 /etc/ssl/certs/ 目录下有系统级的 CA bundle。
  • certificate.pem: 你想要验证的证书文件。

如果验证成功,会输出类似 certificate.pem: OK。如果失败,会给出错误原因,例如:

  • unable to get issuer certificate: 找不到签发该证书的 CA 证书。
  • certificate has expired: 证书已过期。
  • depth lookup:unable to load certificate: 证书链中的某个证书有问题。
  • self signed certificate: 证书是自签名的,且不在信任列表中。

你也可以结合 s_client 来验证远程服务器的证书链:

“`bash

首先获取服务器证书链并保存

openssl s_client -showcerts -connect www.google.com:443 google_chain.pem

然后验证 (注意:需要一个好的 CA bundle 文件)

假设 ca-bundle.pem 是你的信任库

你可能需要先分离服务器证书和中间证书,或让 verify 处理整个文件

验证服务器证书(链中的第一个)

openssl verify -CAfile ca-bundle.pem -untrusted intermediate_certs.pem server_cert.pem

其中 intermediate_certs.pem 包含链中的中间 CA 证书

server_cert.pem 是服务器证书

一个更简单的方法是直接让 s_client 在连接时尝试验证

使用 -verify 选项,可能需要指定 -CAfile 或 -CApath

openssl s_client -connect www.google.com:443 -verify_depth 10 -CAfile /path/to/your/ca-bundle.pem
“`

s_client 在输出的开头也会显示验证结果(Verify return code: 0 (ok) 或其他错误码)。但这依赖于 OpenSSL 配置的默认信任库,可能与浏览器或操作系统的行为不同。

七、 总结

OpenSSL 提供了一套强大而灵活的命令行工具,用于深入检查和分析 SSL/TLS 证书。无论是需要快速查看远程服务器的证书信息,还是详细解析本地存储的证书文件,openssl s_clientopenssl x509 都能胜任。通过掌握这些命令及其常用选项,你可以有效地:

  • 诊断 SSL/TLS 连接问题。
  • 验证服务器身份和证书有效期。
  • 确认证书配置(如 SAN 列表)。
  • 审计证书的安全参数(算法、密钥长度)。
  • 理解和验证证书链。
  • 提取证书特定字段用于脚本处理。

虽然图形界面的工具(如浏览器自带的证书查看器)可能更直观,但 OpenSSL 的命令行工具在自动化、脚本集成、以及提供底层细节方面具有不可替代的优势。熟练运用 OpenSSL 查看证书详情,是每一位需要处理网络安全和加密通信的专业人士必备的技能。通过不断实践这些命令,你将能更自信地应对各种与 SSL/TLS 证书相关的挑战。


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部