OpenSSL 证书链验证详解#
证书链验证是 SSL/TLS 安全的核心机制。本文将详细介绍如何使用 OpenSSL 工具进行证书链验证,确保连接的安全性。
什么是证书链?#
证书链(Certificate Chain)是一系列证书的有序集合,用于验证终端实体证书的有效性。典型的证书链包含:
- 终端实体证书:最终服务的证书
- 中间证书:由 CA 签发的证书
- 根证书:受信任的根 CA 证书
OpenSSL 验证命令#
基本验证#
1
2
3
|
# 验证证书和私钥匹配
openssl x509 -noout -modulus -in server.crt | openssl md5
openssl rsa -noout -modulus -in server.key | openssl md5
|
证书链验证#
1
2
|
# 验证证书链
openssl verify -CAfile root.crt -untrusted intermediate.crt server.crt
|
实战案例:完整证书链验证#
场景描述#
验证包含终端证书、中间证书和根证书的完整证书链。
1. 准备证书文件#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
# 创建测试目录
mkdir -p /tmp/cert-test
cd /tmp/cert-test
# 生成根证书
openssl genrsa -out root.key 4096
openssl req -x509 -new -nodes -key root.key -sha256 -days 3650 \
-out root.crt -subj "/C=CN/ST=Beijing/L=Beijing/O=Test Root CA/CN=Test Root CA"
# 生成中间证书
openssl genrsa -out intermediate.key 2048
openssl req -new -key intermediate.key -out intermediate.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Test Intermediate CA/CN=Test Intermediate CA"
openssl x509 -req -in intermediate.csr -CA root.crt -CAkey root.key \
-CAcreateserial -out intermediate.crt -days 365 -sha256
# 生成终端证书
openssl genrsa -out server.key 2048
openssl req -new -key server.key -out server.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Test Server/CN=test.example.com"
openssl x509 -req -in server.csr -CA intermediate.crt -CAkey intermediate.key \
-CAcreateserial -out server.crt -days 365 -sha256
|
2. 验证证书链#
1
2
3
4
5
|
# 验证终端证书
openssl verify -CAfile root.crt -untrusted intermediate.crt server.crt
# 详细验证过程
openssl verify -verbose -CAfile root.crt -untrusted intermediate.crt server.crt
|
高级验证选项#
1. 检查证书有效期#
1
2
3
4
5
|
# 检查证书有效期
openssl x509 -in server.crt -text -noout | grep "notBefore\|notAfter"
# 验证证书是否过期
openssl x509 -checkend 0 -in server.crt
|
2. 验证证书用途#
1
2
3
4
5
|
# 检查证书扩展字段
openssl x509 -in server.crt -text -noout | grep "Extended Key Usage"
# 验证证书是否支持服务器认证
openssl x509 -in server.crt -purpose sslserver
|
3. 验证主机名匹配#
1
2
3
4
5
|
# 验证证书中的主机名
openssl x509 -in server.crt -text -noout | grep "DNS"
# 使用 OpenSSL 验证主机名匹配
openssl s_client -connect test.example.com:443 -servername test.example.com | openssl x509 -noout -text
|
常见验证问题及解决方案#
1. 证书链不完整#
1
2
3
4
5
|
# 错误示例:缺少中间证书
openssl verify -CAfile root.crt server.crt
# 解决方案:提供完整的证书链
openssl verify -CAfile root.crt -untrusted intermediate.crt server.crt
|
2. 证书过期#
1
2
3
4
5
6
|
# 检查证书过期时间
openssl x509 -in server.crt -enddate -noout
# 创建即将过期的证书进行测试
openssl x509 -req -in server.csr -CA intermediate.crt -CAkey intermediate.key \
-CAcreateserial -out server.crt -days 1 -sha256
|
3. 主机名不匹配#
1
2
3
4
5
|
# 检查证书中的主机名
openssl x509 -in server.crt -text -noout | grep "Subject: CN"
# 验证主机名匹配
openssl s_client -connect wrong.example.com:443 -servername test.example.com
|
实用脚本:证书验证自动化#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
#!/bin/bash
# 证书验证脚本
verify_certificate_chain() {
local server_cert="$1"
local intermediate_cert="$2"
local root_cert="$3"
echo "验证证书链..."
# 检查证书文件是否存在
if [ ! -f "$server_cert" ] || [ ! -f "$intermediate_cert" ] || [ ! -f "$root_cert" ]; then
echo "错误:证书文件不存在"
return 1
fi
# 验证证书链
if openssl verify -CAfile "$root_cert" -untrusted "$intermediate_cert" "$server_cert"; then
echo "✓ 证书链验证成功"
return 0
else
echo "✗ 证书链验证失败"
return 1
fi
}
# 使用示例
verify_certificate_chain "server.crt" "intermediate.crt" "root.crt"
|
验证命令测试#
让我们验证 OpenSSL 证书验证命令是否正常工作:
1
2
3
4
5
6
7
8
9
|
# 创建测试证书
openssl req -x509 -newkey rsa:2048 -nodes -keyout test.key \
-out test.crt -subj "/CN=localhost" -addext "subjectAltName=DNS:localhost"
# 验证自签名证书
openssl verify -CAfile test.crt test.crt
# 检查证书详情
openssl x509 -in test.crt -text -noout
|
证书链验证是确保 SSL/TLS 连接安全的关键步骤。通过 OpenSSL 工具,我们可以:
- 验证证书链的完整性
- 检查证书的有效期和用途
- 确保主机名匹配
- 自动化证书验证流程
定期验证证书链有助于及时发现和解决证书相关问题,确保服务的安全性。
参考来源#