如何绕过 Android 应用程序中的 SSL 证书验证? [英] How to bypass SSL certificate validation in Android app?

查看:23
本文介绍了如何绕过 Android 应用程序中的 SSL 证书验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 Android 应用程序应该能够与任何启用 SSL 的服务器通信.由于我的应用程序是演示应用程序,并且我的客户在登录时在应用程序中添加了他们自己的 SSL 服务器详细信息,所以我不知道我需要验证哪个 SSL 证书.

My Android application should be able to communicate to any SSL enabled servers. As my app is demo application and my customers add their own SSL server details in the app while logging in, so upfront I don't know which SSL certificate I need to validate.

以下是我之前的代码.

public SSLSocketFactory getSSLSocketFactory(String hostname) {
        try {
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            SSLContext context = SSLContext.getInstance("TLS");
            context.init(null, new X509TrustManager[] { new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                }

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

                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
            } }, new SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  HttpsURLConnection.getDefaultSSLSocketFactory();
    }

当我更新到 Playstore 时,它​​被拒绝了,原因如下

When I updated my to playstore, it was rejected with below reason

要正确处理 SSL 证书验证,请更改自定义 X509TrustManager 接口的 checkServerTrusted 方法中的代码,以在服务器提供的证书不符合您的期望时引发 CertificateException 或 IllegalArgumentException.对于技术问题,您可以发布到 Stack Overflow 并使用标签android-security"和TrustManager".

我想更新类似这样的代码

I would like to update my code similar to this

public static HttpClient wrapClient(HttpClient base) {
try {
    SSLContext ctx = SSLContext.getInstance("TLS");
    X509TrustManager tm = new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

        public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException { }

        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    };
    ctx.init(null, new TrustManager[]{tm}, null);
    SSLSocketFactory ssf = new SSLSocketFactory(ctx);
    ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
    ClientConnectionManager ccm = base.getConnectionManager();
    SchemeRegistry sr = ccm.getSchemeRegistry();
    sr.register(new Scheme("https", ssf, 443));
    return new DefaultHttpClient(ccm, base.getParams());
} catch (Exception ex) {
    return null;
}

}

Playstore 接受这个吗?有没有更好的处理方法?

Does playstore accept this? is there any better way to handle this?

提前致谢.

推荐答案

import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.net.URLConnection;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;

public class Example {
    public static void main(String[] args) throws Exception {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] certs, String authType) {
                }
                public void checkServerTrusted(X509Certificate[] certs, String authType) {
                }
            }
        };

        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL"); // Add in try catch block if you get error.
        sc.init(null, trustAllCerts, new java.security.SecureRandom()); // Add in try catch block if you get error.
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

        URL url = new URL("https_url_here");
        URLConnection con = url.openConnection();
        Reader reader = new InputStreamReader(con.getInputStream());
        while (true) {
            int ch = reader.read();
            if (ch==-1) {
                break;
            }
            System.out.print((char)ch);
        }
    }
}

使用这个技巧时要小心!跳过证书验证很危险,只能在测试环境中进行.

Be careful when using this hack! Skipping certificate validation is dangerous and should be done in testing environments only.

这篇关于如何绕过 Android 应用程序中的 SSL 证书验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆