跳到主要内容
ecdsa.com
OpenSSL CLI (openssl s_client / openssl verify)OpenSSL CLI

错误信息

verify error:num=20:unable to get local issuer certificate

也可能输出为

  • Verify return code: 20 (unable to get local issuer certificate)
  • error 20 at 0 depth lookup: unable to get local issuer certificate

s_client 在握手期间输出“verify error:num=20:…”,并在汇总信息中输出“Verify return code: 20 (…)”;openssl verify 输出“error 20 at <depth> depth lookup: …”。默认情况下,s_client 遇到验证错误后会继续执行;加上 -verify_return_error 可以让它直接失败。

OpenSSL CLI (openssl s_client / openssl verify) — X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY

含义

OpenSSL 错误 20(X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY):构建证书链时,OpenSSL 遇到了一张找不到颁发者的证书——服务器发送的证书中没有,信任库中也没有。紧接在错误之前输出的 depth 行指出了缺少颁发者的是哪张证书。curl 的 (60)、Python 的 CERTIFICATE_VERIFY_FAILED 和 Node.js 的 UNABLE_TO_GET_ISSUER_CERT_LOCALLY 背后都是这个代码。

原因

修复方法

  1. 1.

    查看 depth 行

    深度 0 是服务器的证书,更大的数字是服务器发送的中间证书。错误之前的最后一行 depth 就是缺少颁发者的那张证书。

    bash
    echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>&1 | grep -E '^depth|verify'
    # depth=1 CN=Example Corp Issuing CA       <- the highest certificate received
    # verify error:num=20:...                   <- its issuer is not in the trust store
  2. 2.

    用预期的根证书测试

    用 -CAfile 指定正确的根证书(并加上 -verify_return_error,让失败直接中止),就能看出该根证书能否补全证书链;“Verify return code: 0 (ok)”表示可以。

    bash
    # Verify against a specific root (exit code and "Verify return code: 0 (ok)" confirm it)
    echo | openssl s_client -connect api.example.com:443 -servername api.example.com \
      -CAfile corp-root-ca.pem -verify_return_error 2>&1 | grep 'Verify return code'
  3. 3.

    离线验证证书文件

    把根证书作为 -CAfile、中间证书作为 -untrusted 传给 openssl verify;单独一张叶子证书无法验证。

    bash
    # Offline: root as trust anchor, intermediate(s) as untrusted helpers
    openssl verify -CAfile corp-root-ca.pem -untrusted intermediate.pem server.pem
  4. 4.

    把根证书安装到系统信任库

    如果证书链本来就应该终止于公司根证书,就把它添加到发行版的信任库中;之后这台机器上基于 OpenSSL 的工具都会信任它。

    bash
    sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt
    sudo update-ca-certificates     # openssl reads /etc/ssl/certs by default on Debian/Ubuntu

相关错误

浏览完整的签名错误库