Volley SSL - 主机名未经验证

4

我正在开发一个Android应用程序,需要访问HTTPS地址。我使用Volley请求数据,但现在我遇到了这个错误com.android.volley.NoConnectionError: java.io.IOException: Hostname '<address>' was not verified

为了获取SSL工厂,我执行以下操作:

private static SSLSocketFactory getSocketFactory() {
    SSLSocketFactory socketFactory = null;


    try {
        final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
        final BufferedInputStream bis = new BufferedInputStream(sContext.getResources().openRawResource(R.raw.cert)) ;

        Certificate certificate;
        try {
            certificate = certificateFactory.generateCertificate(bis);
        } finally {
            bis.close();
        }

        final String keyStoreType = KeyStore.getDefaultType();
        final KeyStore keyStore = KeyStore.getInstance(keyStoreType);
        keyStore.load(null, null);
        keyStore.setCertificateEntry("ca", certificate);

        final String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keyStore);
        final SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        socketFactory = sslContext.getSocketFactory();
    } catch (Exception e) {
        Log.w(TAG, Log.getStackTraceString(e));
    }
    return socketFactory;
}

队列初始化:
final HttpStack stack = new HurlStack(null, getSocketFactory());
final Cache cache = new NoCache();
final Network network = new BasicNetwork(stack);
sRequestQueue = new RequestQueue(cache, network);
sRequestQueue.start();

以下是堆栈跟踪:

    com.android.volley.NoConnectionError: java.io.IOException: Hostname 'url' was not verified
09-04 11:15:33.198   W/System.err﹕ at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:151)
09-04 11:15:33.198   W/System.err﹕ at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:112)
09-04 11:15:33.198   W/System.err﹕ Caused by: java.io.IOException: Hostname 'hml.services.vivara.com.br' was not verified
09-04 11:15:33.198   W/System.err﹕ at com.android.okhttp.Connection.upgradeToTls(Connection.java:201)
09-04 11:15:33.198   W/System.err﹕ at com.android.okhttp.Connection.connect(Connection.java:151)
09-04 11:15:33.198   W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:276)
09-04 11:15:33.198   W/System.err﹕ at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
09-04 11:15:33.198   W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:373)
09-04 11:15:33.198   W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:106)
09-04 11:15:33.198   W/System.err﹕ at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:208)
09-04 11:15:33.198   W/System.err﹕ at com.android.okhttp.internal.http.DelegatingHttpsURLConnection.getOutputStream(DelegatingHttpsURLConnection.java:218)
09-04 11:15:33.198   W/System.err﹕ at com.android.okhttp.internal.http.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:25)
09-04 11:15:33.198   W/System.err﹕ at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:240)
09-04 11:15:33.198   W/System.err﹕ at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:210)
09-04 11:15:33.198   W/System.err﹕ at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:106)
09-04 11:15:33.198   W/System.err﹕ at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:96)

我搜索了这个错误,但是没有找到适用于我的情况的解决方案。有人能帮帮我吗?

3个回答

6
假设你的服务器应用托管在一台服务器上,该服务器具有服务器证书,其中“发行给”是“localhost”,例如。然后,在验证方法中,您可以验证“localhost”。
HostnameVerifier hostnameVerifier = new HostnameVerifier() {
    @Override
    public boolean verify(String hostname, SSLSession session) {
        HostnameVerifier hv =
            HttpsURLConnection.getDefaultHostnameVerifier();
        return hv.verify("localhost", session);
    }
};

您可以在以下链接中了解更多信息:
  1. HostnameVerifier

    如果URL的主机名与对等方的标识主机名不匹配,则在握手期间使用它。

  2. 主机名验证常见问题

    发生这种情况的一个原因是由于服务器配置错误。该服务器配置了一个证书,该证书没有与您尝试到达的服务器匹配的主题或主题替代名称字段...

然后,在您的Volley应用程序中,您可以创建一个HurlStack,覆盖其中的createConnection,并为httpsURLConnection设置setHostnameVerifier

希望这可以帮助您!


1
HurlStack 中的 createConnection 方法返回的是 HttpURLConnection 而不是 HttpsURLConnection,因此没有 setHostnameVerifier。请提供更详细的答案,说明如何为此情况创建自定义的 HurlStack 对象。谢谢! - toom
1
@toom 你可以在我的另一个回答中找到一个例子,网址为https://dev59.com/71wY5IYBdhLWcg3wYm8B#32674422。 - BNK

-2

这是一个可能的解决方案

HostnameVerifier allHostsValid = new HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
};

那是什么意思? - Herr Derb

-6

当您的网络在http请求期间断开连接时,会出现此错误。因此,请确保您的网络稳定,然后再检查。


我认为你可以在https://developer.android.com/training/articles/security-ssl.html#CommonHostnameProbs找到这个错误的原因。 - BNK

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