使用3G时证书路径的信任锚点未找到,但在WiFi上正常工作。

7

我的Android项目使用API 15。我正在使用HttpsURLConnection类通过https连接到服务器。在WiFi上一切都正常,但如果我关闭WiFi并使用3G运行,则会出现以下问题:

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.       at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:413)
   at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:257)       at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:210)
   at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:477)
   at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:432)
   at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:282)
   at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:232)       at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:80)
   at libcore.net.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:188)       at libcore.net.http.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:280)

如果我做错了什么,为什么它可以在WiFi上运行?

这里有更多的信息。

如果我使用openssl查看服务器证书信息,

echo | openssl s_client -connect myserver.com:443

返回服务器级别的自签名证书,而
echo | openssl s_client -connect myserver.com:443 -servername myserver.com

返回“正确”的证书。我的服务器上有多个虚拟主机,每个主机都有自己的rapidssl颁发的证书,所以我认为我需要使用支持TLS的客户端。至少这是我在Apache启动日志中看到的信息的解释:

Name-based SSL virtual hosts only work for clients with TLS server name indication support

如果我到目前为止是正确的,这是否意味着我的手机3g网络可能会影响到TLS,或者我应该做些其他的事情?
我可以通过子类化DefaultHttpClient并导入一个包含服务器自签名证书的密钥库来使事情在3g上工作,但这绝对不是我的首选选项。

服务器的URL是什么? - jww
1个回答

0

添加-servername选项只是在Client Hello消息中设置服务器名称指示字段,这有助于我们选择正确的证书,如果目标主机包含多个证书,就像您的情况一样。但是,这与问题无关。

在SSL握手期间,证书以主题/颁发者对的形式交付,形成证书链。

例如,google.com的证书链如下:

openssl s_client -connect google.com:443
CONNECTED(00000003)
depth=2 C = US, O = GeoTrust Inc., CN = GeoTrust Global CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.google.com
   i:/C=US/O=Google Inc/CN=Google Internet Authority G2
 1 s:/C=US/O=Google Inc/CN=Google Internet Authority G2
   i:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
 2 s:/C=US/O=GeoTrust Inc./CN=GeoTrust Global CA
   i:/C=US/O=Equifax/OU=Equifax Secure Certificate Authority
---

一旦接收到,客户端会尝试从底部向顶部(根)验证证书链中的所有颁发者。如果客户端无法验证根证书,则会出现“找不到用于认证路径的信任锚点”的消息。

因此,回到WiFi / 3G问题,可能您的移动网络DNS无法解析证书链中间颁发者之一的地址。

更新:

您可以将颁发者证书放入您的APK中,并通过代码中的TrustManager添加。这种方法可以克服访问网络限制(如果有)。


DNS与证书验证有什么关系? - user207421
如果设备CA密钥库中缺少中间证书之一,它可以通过哪个协议找到授权?此外,请检查此答案:https://dev59.com/epnks4cB2Jgan1znxvM9 - Efe Kahraman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接