openssl verify 是 OpenSSL 中最常用的证书验证工具,用于验证证书链的完整性和有效性。本文详细介绍其常用选项和实战场景。
基本语法#
1
|
openssl verify [options] certificate.pem
|
常用选项#
指定可信 CA#
| 选项 |
说明 |
-CAfile <file> |
指定一个包含可信 CA 证书的文件 |
-CApath <dir> |
指定可信 CA 证书目录(需要哈希索引) |
-CAstore <uri> |
从 URI 加载可信证书 |
1
2
3
4
5
|
# 使用 CAfile 验证
openssl verify -CAfile ca.crt server.crt
# 同时使用 CAfile 和 CApath
openssl verify -CAfile ca.crt -CApath /etc/ssl/certs server.crt
|
指定中间证书#
1
2
|
# -untrusted 指定中间证书(证书链中的非可信证书)
openssl verify -CAfile root.crt -untrusted intermediate.crt server.crt
|
常用验证选项#
| 选项 |
说明 |
-partial_chain |
接受部分链验证(只要链到某个可信 CA 即可) |
-show_chain |
显示完整的证书链信息 |
-purpose <purpose> |
验证证书用途(sslserver, sslclient, etc.) |
-policy_check |
启用 RFC 5280 策略检查 |
-verify_depth <n> |
限制证书链深度 |
实战场景#
场景一:验证完整证书链#
1
2
3
4
5
|
# 创建测试证书链
# 1. CA -> 2. 中间 CA -> 3. 服务器证书
# 使用 -untrusted 指定中间证书
openssl verify -CAfile ca.crt -untrusted intermediate.crt server.crt
|
输出示例:
带链信息显示:
1
|
openssl verify -CAfile ca.crt -untrusted intermediate.crt -show_chain server.crt
|
输出:
1
2
3
4
5
|
server.crt: OK
Chain:
depth=0: CN = example.com (untrusted)
depth=1: CN = Test Intermediate CA (untrusted)
depth=2: CN = Test CA
|
场景二:部分链验证#
当只有服务器证书和中间证书,想验证是否被某个根 CA 信任:
1
2
3
4
5
|
# 验证到可信 CA 即可,不需要完整链
openssl verify -CAfile ca.crt -partial_chain server.crt
# 也可以直接验证中间证书是否被 CA 信任
openssl verify -CAfile ca.crt -partial_chain intermediate.crt
|
场景三:验证证书用途#
1
2
3
4
5
6
7
|
# 验证服务器证书用途
openssl verify -CAfile ca.crt -untrusted intermediate.crt \
-purpose sslserver server.crt
# 验证客户端证书用途
openssl verify -CAfile ca.crt -untrusted intermediate.crt \
-purpose sslclient client.crt
|
场景四:检查吊销状态#
1
2
3
4
5
6
7
8
9
10
11
|
# 检查叶子证书 CRL
openssl verify -CAfile ca.crt -untrusted intermediate.crt \
-CRLfile crl.pem -crl_check server.crt
# 检查完整链的 CRL
openssl verify -CAfile ca.crt -untrusted intermediate.crt \
-CRLfile crl.pem -crl_check_all server.crt
# 尝试从 CDP 下载 CRL
openssl verify -CAfile ca.crt -untrusted intermediate.crt \
-crl_download server.crt
|
场景五:使用 CApath 目录#
1
2
3
4
5
6
7
|
# 创建哈希索引目录
mkdir -p /tmp/cacerts
cp ca.crt /tmp/cacerts/
c_rehash /tmp/cacerts/
# 使用 CApath 验证
openssl verify -CApath /tmp/cacerts -untrusted intermediate.crt server.crt
|
场景六:策略检查#
1
2
3
|
# 启用策略检查,需要指定策略
openssl verify -CAfile ca.crt -untrusted intermediate.crt \
-policy_check -policy anyPolicy server.crt
|
场景七:设置验证深度#
1
2
3
|
# 限制链深度,防止中间人攻击
openssl verify -CAfile ca.crt -untrusted intermediate.crt \
-verify_depth 2 server.crt
|
场景八:指定验证时间#
1
2
3
|
# 验证证书在某个历史时间点的状态
openssl verify -CAfile ca.crt -untrusted intermediate.crt \
-attime 1704067200 server.crt # 2024-01-01 00:00:00 UTC
|
常见错误排查#
error 20: unable to get local issuer certificate#
原因:缺少中间证书或根 CA
解决:使用 -untrusted 添加中间证书
1
|
openssl verify -CAfile ca.crt -untrusted intermediate.crt server.crt
|
error 18: self signed certificate#
原因:证书自签名,不被信任
解决:如果是自己测试,可以使用 -partial_chain 接受自签名证书
1
|
openssl verify -CAfile myca.crt -partial_chain mycert.crt
|
error 2: unable to get issuer certificate#
原因:找不到证书颁发者
解决:确保 -CAfile 包含正确的根 CA
error 10: certificate has expired#
原因:证书已过期
解决:检查证书有效期或使用 -attime 指定历史时间点
1
2
|
# 查看证书有效期
openssl x509 -in server.crt -noout -dates
|
完整验证脚本示例#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#!/bin/bash
# verify-cert.sh - 证书链验证脚本
CA_FILE="ca.crt"
UNTRUSTED="intermediate.crt"
CERT="$1"
if [ -z "$CERT" ]; then
echo "Usage: $0 <certificate>"
exit 1
fi
echo "=== 基本验证 ==="
openssl verify -CAfile "$CA_FILE" -untrusted "$UNTRUSTED" "$CERT"
echo -e "\n=== 显示完整链 ==="
openssl verify -CAfile "$CA_FILE" -untrusted "$UNTRUSTED" \
-show_chain "$CERT"
echo -e "\n=== 证书信息 ==="
openssl x509 -in "$CERT" -noout -subject -issuer -dates
|
| 场景 |
推荐命令 |
| 验证完整链 |
openssl verify -CAfile root.crt -untrusted intermediate.crt server.crt |
| 快速验证 |
openssl verify -CAfile root.crt -partial_chain server.crt |
| 调试模式 |
openssl verify -CAfile root.crt -untrusted intermediate.crt -show_chain -verbose server.crt |
| 检查吊销 |
openssl verify -CAfile root.crt -untrusted intermediate.crt -crl_check server.crt |
掌握这些用法,可以快速诊断证书链问题,确保 HTTPS 服务的正确配置。
参考来源