ActPi向阳技术栈
← 返回文章列表

SSL 证书校验错误 Trust anchor for certification path not found

文章目录
  1. 问题描述
  2. 问题发现
  3. 问题原因
  4. 解决方案
  5. 最后

问题描述

在使用 acme.sh脚本签发的Let’s Encrypt 免费SSL证书,在android中无法通过SSL系统验证,出现以下异常Trust anchor for certification path not found

javax.net.ssl.SSLHandshakeException:
  java.security.cert.CertPathValidatorException:
    Trust anchor for certification path not found.

问题发现

安卓客户端无法连接域名服务器,浏览器直接打开网址正常,ssl连接正常,在SDK里连接失败。

错误消息为:

 javax.net.ssl.SSLHandshakeException:
   java.security.cert.CertPathValidatorException:
     Trust anchor for certification path not found.

问题原因

直接让 nginx配置文件使用了acme.sh脚本签发的<doman>.cer文件,这里面的文件都是内部使用,直接使用会导致服务器证书链配置错误,缺少中间证书设置。

解决方案

参考stackoverflow

  1. 使用openssl检查证书

    openssl s_client -debug -connect www.mafxcc.com:443

    可能会出现:

    Verify return code: 21 (unable to verify the first certificate)

    而且在前面的输出里有:

    depth=0 OU = Domain Control Validated, CN = www.domain.com
    verify error:num=20:unable to get local issuer certificate
    verify return:1 depth=0 OU = Domain Control Validated, CN =  www.domain.com
    verify error:num=27:certificate not trusted
    verify return:1 depth=0 OU = Domain Control Validated, CN =  www.domain.com
    verify error:num=21:unable to verify the first certificate`

    证书链只包含一个元素:

    Certificate chain  
    0 s:CN = domain.com  
    i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3

    但是应该有将一个链中的签名权限引用回安卓信任的权限(Verisign、GlobalSign等):

    ---  
    Certificate chain  
    0 s:CN = domain.com  
    i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3  
    1 s:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3  
    i:O = Digital Signature Trust Co., CN = DST Root CA X3  
    ---  
  2. 在用acme.sh把证书生成以后, 需要把证书安装到真正需要用它的地方

    注意: 默认生成的证书都放在安装目录下: ~/.acme.sh/.com/, 不要直接使用此目录下的文件, 例如: 不要直接让 nginx/apache 的配置文件使用这下面的文件. 这里面的文件都是内部使用, 而且目录结构可能会变化.

    正确的使用方法是使用 --installcert 命令,并指定目标位置, 然后证书文件会被安装到相应的位置, 例如:

    $ acme.sh --installcert -d <domain>.com \
    --key-file /etc/nginx/ssl/<domain>.key \
    --fullchain-file /etc/nginx/ssl/fullchain.cer \
    --reloadcmd "service nginx force-reload"  

最后

在 Nginx 的配置 ssl_certificate 使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/<domain>.cer !

重启 Nginx 后再次验证 SSL证书。