SSL 证书校验错误 Trust anchor for certification path not found
问题描述
在使用 acme.sh脚本签发的Let’s Encrypt 免费SSL证书,在android中无法通过SSL系统验证,出现以下异常Trust anchor for certification path not found
1 | javax.net.ssl.SSLHandshakeException: |
问题发现
安卓客户端无法连接域名服务器,浏览器直接打开网址正常,ssl连接正常,在SDK里连接失败。
错误消息为:
1 | javax.net.ssl.SSLHandshakeException: |
问题原因
直接让 nginx配置文件使用了acme.sh脚本签发的<doman>.cer
文件,这里面的文件都是内部使用,直接使用会导致服务器证书链配置错误,缺少中间证书设置。
解决方案
-
使用openssl检查证书
1
openssl s_client -debug -connect www.mafxcc.com:443
可能会出现:
1
Verify return code: 21 (unable to verify the first certificate)
而且在前面的输出里有:
1
2
3
4
5
6depth=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`证书链只包含一个元素:
1
2
3Certificate chain
0 s:CN = domain.com
i:C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3但是应该有将一个链中的签名权限引用回安卓信任的权限(Verisign、GlobalSign等):
1
2
3
4
5
6
7---
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
命令,并指定目标位置, 然后证书文件会被安装到相应的位置, 例如:1
2
3
4$ 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证书。