WebView和SSL证书

时间:2014-07-04 11:13:23

标签: android ssl android-webview

我在使用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可信凭证的所有证书都是可信的。

1 个答案:

答案 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是设置的   唯一端口上的备用虚拟主机,因此它是明确的   要返回的服务器证书。

希望它有所帮助。