SSL 证书校验错误 Trust anchor for certification path not found
问题描述
在使用 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文件,这里面的文件都是内部使用,直接使用会导致服务器证书链配置错误,缺少中间证书设置。
解决方案
-
使用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 --- -
在用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证书。