OpenSSL CLI (openssl s_client / openssl verify)OpenSSL CLI
错误信息
verify error:num=18:self-signed certificate
也可能输出为
- verify error:num=18:self signed certificate
- Verify return code: 18 (self-signed certificate)
- error 18 at 0 depth lookup: self-signed certificate
OpenSSL 3.x 输出“self-signed”,1.1.1 输出“self signed”。s_client 显示“verify error:num=18:…”和“Verify return code: 18 (…)”;openssl verify 显示“error 18 at 0 depth lookup: …”。
OpenSSL CLI (openssl s_client / openssl verify) — X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
含义
OpenSSL 错误 18(X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT):深度 0 处的证书是自签名的(它的颁发者就是它自己),并且不在信任库中。它上面没有 CA,所以任何中间证书或证书包都无济于事;必须直接信任这张证书,或者换成由 CA 签发的证书。
原因
服务器使用自签名证书
常见开发服务器、专用设备、管理界面和刚安装的服务,起初往往使用自动生成的证书。
对未知名称提供了默认证书
偶见反向代理和 Ingress 会用自签名的默认证书应答没有配置的名称;检查 SNI 和路由。
对根证书运行了 openssl verify
偶见不加 -CAfile root.pem 运行 openssl verify root.pem 时,任何自签名根证书都会报告错误 18,即使它是有效的。
修复方法
- 1.
确认主体与颁发者相同
如果主体等于颁发者,证书就是自签名的;需要与预期值比较的是它的指纹。
bash echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null \ | openssl x509 -noout -subject -issuer -fingerprint -sha256 # subject == issuer: self-signed - 2.
测试时只信任这一张证书
把证书本身作为 -CAfile 传入,OpenSSL 就只接受这一张证书。先通过可信渠道确认指纹。
bash # Trust this exact certificate for a check (after confirming the fingerprint out of band) echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null | openssl x509 -out api.pem echo | openssl s_client -connect api.example.com:443 -servername api.example.com -CAfile api.pem 2>&1 | grep 'Verify return code' - 3.
用根证书自身验证它
自签名根证书只有作为信任锚时才能通过验证:把它作为 -CAfile 传入。
bash # Verifying a root CA certificate itself needs the root as its own trust anchor openssl verify -CAfile root.pem root.pem # root.pem: OK