You need to enable JavaScript to run this app. 不同OpenSSL版本下证书验证报错error 20:无法获取本地颁发者证书
优惠活动
大模型
产品
解决方案
定价
更多

不同OpenSSL版本下证书验证报错error 20:无法获取本地颁发者证书

证书跨版本验证异常根因与修复

问题现象

  • 同一套自签根CA、服务器/客户端证书,在Ubuntu 18.04内置的OpenSSL 1.1.1(2018.09构建)环境下可正常通过openssl verify校验
  • 在Ubuntu 20.04内置的OpenSSL 1.1.1f,以及同系列后续小版本(1.1.1g/1.1.1i,Nginx官方镜像内置)环境下,执行相同验证命令会报error 20 at 0 depth lookup: unable to get local issuer certificate
  • 服务器证书、客户端证书均存在该问题,直接导致Nginx mTLS场景下的客户端证书校验失败

核心根因

OpenSSL从1.1.1e版本(2020年3月发布,是1.1.1f的基线版本)开始,调整了可信CA证书的校验逻辑:

  • 旧版本仅检查CA证书是否携带keyCertSign权限位,不会校验keyUsage字段的配置合理性
  • 新版本会强制校验:如果作为可信CA使用的证书在keyUsage中包含keyEncipherment或dataEncipherment权限位,就会直接将该证书判定为终端实体证书,从可信CA列表中过滤掉
  • 被过滤的根CA自然无法匹配下级证书的颁发者信息,最终触发error 20的“无法获取本地颁发者证书”错误

对照你的证书生成脚本,两个配置问题完全触发了上述严格校验规则:

  1. 自签根CA的keyUsage配置错误加入了keyEncipherment、dataEncipherment等终端实体专属权限
  2. 下级服务器、客户端等终端证书的keyUsage配置错误加入了keyCertSign、cRLSign等CA专属权限,不符合X.509证书规范

修复步骤

  1. 调整自签根CA的keyUsage配置,替换原有全权限列表为仅CA需要的权限:
    # 原配置行替换为:
    -addext "keyUsage = digitalSignature, nonRepudiation, keyCertSign, cRLSign"
    
    删除所有终端实体类的权限位(keyEncipherment、dataEncipherment、keyAgreement、encipherOnly、decipherOnly)
  2. 调整下级终端证书的keyUsage配置,去掉CA专属权限:
    # 服务器证书配置替换为:
    keyUsage = digitalSignature, keyEncipherment
    extendedKeyUsage = serverAuth
    # 客户端证书配置替换为:
    keyUsage = digitalSignature, keyEncipherment
    extendedKeyUsage = clientAuth
    
    删除原有配置中keyCertSign、cRLSign、keyAgreement、encipherOnly、decipherOnly等不相关的权限位
  3. 在下级证书的openssl配置段中补充链匹配扩展,避免证书匹配歧义:
    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always, issuer:always
    
  4. 重新生成整套证书链后,即可同时兼容新旧版本OpenSSL的校验逻辑,Nginx mTLS的客户端证书校验也会恢复正常

补充说明

  • 该问题和加密算法兼容性、证书签名强度无关,纯粹是OpenSSL校验规则严格化导致的配置不兼容
  • 无需降级OpenSSL版本,按照X.509规范调整证书的权限配置即可全版本兼容

内容的提问来源于stack exchange,提问作者HXK8

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 05:24:05