java - Android SSL 主机名未验证

标签 java android ssl

我有一个自签名服务器硬编码端口 52428。我的客户端应用程序不断收到“主机名未验证”,即使我重写 HostNameVerifier 以始终返回 true。当我将主机名从 IP 地址更改为 DNS 时,弹出另一个错误消息“无法解析主机:没有与主机名关联的地址”

这是我的代码:

private class SSLConnect extends AsyncTask<Void, Void, String> {
    @Override
    protected String doInBackground(Void... values) {
        //String https_url = "https://www.google.com/";
        //String https_url = "https://192.168.0.106:52428/webserveradmin/preferences";
        String https_url = "https://home-pc:52428/webserveradmin/preferences/";
        String response;

        try {
            TrustManager[] tm = new TrustManager[]{
                new X509TrustManager() {
                    @Override
                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                    }

                    @Override
                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

                    }

                    @Override
                    public X509Certificate[] getAcceptedIssuers() {
                        //return new X509Certificate[0];
                        return null;
                    }
                }
            };

            URL url;
            try {
                url = new URL(https_url);
            }
            catch (MalformedURLException e) {
                return "Error URL: " + e.getMessage();
            }

            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
            try {
                conn.setDefaultHostnameVerifier(new NullHostNameVerifier());
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, tm, new SecureRandom());
                conn.setSSLSocketFactory(sc.getSocketFactory());
                conn.setRequestMethod("GET");
                conn.setRequestProperty("Authorization", "Basic " + Base64.encode("sa:sa".getBytes(), Base64.DEFAULT));
                conn.connect();

                InputStream in = conn.getInputStream();
                BufferedReader r = new BufferedReader(new InputStreamReader(in));
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = r.readLine()) != null) {
                    sb.append(line);
                }
                response = sb.toString();

            } catch (GeneralSecurityException e) {
                return "Error Security: " + e.getMessage();
            }
        }
        catch(Exception e){
            return "Error SSL: " + e.getMessage();
        }
        return response;
    }

    @Override
    protected void onProgressUpdate(Void... values) {

    }

    @Override
    protected void onPostExecute(String result) {
        Toast.makeText(ctxt, result, Toast.LENGTH_LONG).show();
    }
}

public class NullHostNameVerifier implements HostnameVerifier{
    @Override
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }
}

最佳答案

主机名 validator 只关心验证主机名,而不关心信任链。但是对于自签名证书,您没有通向本地受信任证书的信任链。

除此之外,只是禁用证书检查是一个非常糟糕的主意,因为这样你不仅会接受你的自签名证书,还会接受任何证书,因此你将对人开放-中间攻击。另见 SSL Vulnerability in ******** VU#582497 . 要正确执行此操作,请改用证书/公钥固定。有关更详细的说明和示例代码,请参阅 OWSAP .

关于java - Android SSL 主机名未验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27671168/

相关文章:

security - 为什么浏览器接受通过非安全 (HTTP) 连接发送的安全 cookie?

java - 未加载新创建的行中的默认值

java - 没有 onActivityResult 的 Activity 之间的 Android 通信

android - 在 Android 应用程序中比较日期

ssl - .NET Core 在处理 HTTPS 证书时出现未知错误

spring-boot - Spring websocket (WSS) 与 angular sockjs (HTTPS) 在安全 web socket 服务器 (tomcat) 上

java - 最新代码中的 FHIR _id 至 id 更改

java - 什么是NullPointerException,我该如何解决?

java - 如何使用 Spring Java 在 JSP 中的文本框中保留用户名

java - Android WebView 未加载