我在使用Androids WebView加载SSL安全网页时遇到问题。我总是得到如下错误:
onReceivedSslError: primary error: 3 certificate: Issued to: CN=intranet.<company>.de,C=DE,O=<company>,OU=<compay org unit>
我已经通过Settings-&gt; Security-&gt;从SD卡安装,已将此服务器证书链的所有证书安装到Android的钥匙串中。我甚至可以看到其中一个安装的证书完全匹配LogCat的错误输出。
如果我使用默认的浏览器应用程序会更加奇怪:即使我卸载之前提到的所有证书,它也会毫无问题地加载页面。
我不知道如何在不信任所有证书的情况下通过调用handler.proceed()
中的onReceivedSslError()
来解决这个问题,这是一个潜在的安全问题。
任何帮助表示赞赏。谢谢!
干杯 比约恩
编辑:根证书是自签名的,因为它仅用于Intranet服务器。我认为我添加到Android可信凭证的所有证书都是可信的。
答案 0 :(得分:2)
当使用自签名证书连接到服务时,应使用onReceiveSslError()
和handler.proceed()
,webview与它们不相符。
我现在想的是服务器端的ssl实现。如果您有多个具有相同证书的服务,请检查 SNI 支持以及是否配置良好。然后查看您要连接的服务是否返回正确的证书。还要检查服务器上的使用者备用名称,并根据您的需要进行配置。
对于该任务,您可以使用这些命令。
openssl s_client -showcerts -connect yourhost.com:443
openssl s_client -connect yourhost.com:443
openssl s_client -servername yourhost.com -connect yourhost.com:443
openssl s_client -connect yourhost.com:443 | openssl x509 -text
您可以在此处获得Android文档中的更多信息
主机名验证的常见问题如上所述 在本文开头,验证SSL有两个关键部分 连接。第一种是验证证书来自可信任 来源,这是上一节的重点。这个焦点 部分是第二部分:确保与您交谈的服务器 提供正确的证书。如果没有,你通常会看到 像这样的错误:
java.io.IOException:主机名'example.com'未经过验证 在libcore.net.http.HttpConnection.verifySecureSocketHostname(HttpConnection.java:223) at libcore.net.http.HttpsURLConnectionImpl $ HttpsEngine.connect(HttpsURLConnectionImpl.java:446) 在libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290) 在libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240) at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282) 在libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177) at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271) 出现这种情况的一个原因是服务器配置错误。该 服务器配置了没有主题的证书 或者使用与您所在服务器匹配的替代名称字段 试图达到。可以使用一个证书 许多不同的服务器例如,查看google.com 证书与openssl s_client -connect google.com:443 | OpenSSL的 x509 -text您可以看到支持* .google.com的主题但是 还为* .youtube.com,* .android.com和。提供替代名称 其他。仅在连接的服务器名称时才会发生此错误 未被证书列为可接受的。
不幸的是,这也可能出于另一个原因:虚拟 托管。使用HTTP共享多个主机名的服务器时, Web服务器可以从HTTP / 1.1请求告知哪个目标 客户端正在寻找的主机名。不幸的是,这很复杂 使用HTTPS,因为服务器必须知道要返回哪个证书 在它看到HTTP请求之前。要解决这个问题,请更新 SSL的版本,特别是TLSv.1.0和更高版本,支持服务器名称 指示(SNI),允许SSL客户端指定预期的 服务器的主机名,以便返回正确的证书。
幸运的是,自Android 2.3以来,HttpsURLConnection支持SNI。 不幸的是,Apache HTTP Client没有,这是众多之一 我们不鼓励使用它的原因。一个解决方法,如果您需要支持 Android 2.2(及更早版本)或Apache HTTP Client是设置的 唯一端口上的备用虚拟主机,因此它是明确的 要返回的服务器证书。
希望它有所帮助。