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
server.crt: OK

带链信息显示:

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 服务的正确配置。


参考来源