【问题标题】:Java SSLException: hostname in certificate didn't match in android applicationJava SSLException:证书中的主机名在 android 应用程序中不匹配
【发布时间】:2016-03-11 13:51:34
【问题描述】:

我正在开发一个使用休息服务并访问我的网站(具有 SSL)以获取数据的 android 应用程序。我在同一台服务器上还有一些其他域。

现在,当我尝试访问我的网站时,它正在检查其他域 例如

我的网站: 'abc.xyz.com'

其他域: '*.mno.com'

REST URL 例如: https://abc.xyz.com/restapiservice/data/{dataid}?restkey={rest-api-key}

错误:

javax.net.ssl.SSLException:证书中的主机名不匹配: != .mno.com> 或 .mno.com> 或者

代码:

try {
            // http client
            DefaultHttpClient httpClient;
            final HttpParams httpParams = new BasicHttpParams();
            HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
            httpClient = new DefaultHttpClient(httpParams);

            //DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpEntity httpEntity = null;
            HttpResponse httpResponse = null;

            // Checking http request method type
            if (method == POST) {
                HttpPost httpPost = new HttpPost(url);
                // adding post params
                if (params != null) {
                    httpPost.setEntity(new UrlEncodedFormEntity(params));
                }

                httpResponse = httpClient.execute(httpPost);

            } else if (method == GET) {
                // appending params to url
                if (params != null) {
                    String paramString = URLEncodedUtils
                            .format(params, "utf-8");
                    url += String.format("?%s", paramString);
                }
                HttpGet httpGet = new HttpGet(url);

                httpResponse = httpClient.execute(httpGet);

            }
            httpEntity = httpResponse.getEntity();
            response = EntityUtils.toString(httpEntity, HTTP.UTF_8);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

我已经尝试过解决方案:

        try {

        HostnameVerifier hostnameVerifier = org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

        DefaultHttpClient client = new DefaultHttpClient();

        //Added my part

        final HttpParams httpParams = new BasicHttpParams();
        HttpConnectionParams.setConnectionTimeout(httpParams, 30000);
        client = new DefaultHttpClient(httpParams);

        //End my part

        SchemeRegistry registry = new SchemeRegistry();
        SSLSocketFactory socketFactory = SSLSocketFactory.getSocketFactory();
        socketFactory.setHostnameVerifier((X509HostnameVerifier) hostnameVerifier);
        registry.register(new Scheme("https", socketFactory, 443));
        SingleClientConnManager mgr = new SingleClientConnManager(client.getParams(), registry);
        DefaultHttpClient httpClient = new DefaultHttpClient(mgr, client.getParams());

        // Set verifier
        HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);

        HttpEntity httpEntity = null;
        HttpResponse httpResponse = null;

        // Checking http request method type
        if (method == POST) {
            HttpPost httpPost = new HttpPost(url);
            // adding post params
            if (params != null) {
                httpPost.setEntity(new UrlEncodedFormEntity(params));
            }

            httpResponse = httpClient.execute(httpPost);

        } else if (method == GET) {
            // appending params to url
            if (params != null) {
                String paramString = URLEncodedUtils
                        .format(params, "utf-8");
                url += String.format("?%s", paramString);
            }
            HttpGet httpGet = new HttpGet(url);

            httpResponse = httpClient.execute(httpGet);

        }
        httpEntity = httpResponse.getEntity();
        response = EntityUtils.toString(httpEntity, HTTP.UTF_8);

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

但我不想使用它,因为它可能会导致一些安全威胁(我不想使用“ALLOW_ALL_HOSTNAME_VERIFIER”)

请给我一些其他的替代方案。

【问题讨论】:

  • 您的服务器是否设置为SNI?在同一台服务器上拥有多个域需要 SNI 才能获得正确的 SSL/TLS 支持,AFAIK。

标签: java android rest ssl apache-httpclient-4.x


【解决方案1】:

也许这对你有帮助。

private HttpURLConnection getHttpConnection(String param)
        throws IOException, NoSuchAlgorithmException,
        KeyManagementException {

    URL url = new URL(URL + param);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    if (conn instanceof HttpsURLConnection) {
        HttpsURLConnection httpsConn = (HttpsURLConnection) conn;
        SSLContext sc;
        sc = SSLContext.getInstance(TLS);
        sc.init(null, null, new java.security.SecureRandom());
        httpsConn.setSSLSocketFactory(sc.getSocketFactory());
    }

    // set Timeout and method
    conn.setReadTimeout(TIMEOUT);
    conn.setConnectTimeout(TIMEOUT);
    conn.setRequestMethod(POST);
    conn.setDoInput(true);
    conn.setDoOutput(true);
    return conn;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-16
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 2018-06-18
    相关资源
    最近更新 更多