Android 设置信任所有证书

在 Android 开发中,我们经常需要与服务器进行数据交互,而服务器通常会使用 SSL/TLS 证书来确保通信的安全性。默认情况下,Android 会对服务器的证书进行验证,以确保其有效性和可信度。然而,在某些情况下,我们可能需要信任所有证书,例如在测试环境中或者与自签名证书进行通信时。本文将介绍如何在 Android 中设置信任所有证书。

SSL/TLS 证书

在介绍如何信任所有证书之前,我们先来了解一下 SSL/TLS 证书的相关知识。

SSL(Secure Sockets Layer)和 TLS(Transport Layer Security)是用于在网络上建立安全通信的协议。它们使用公钥加密来确保数据的机密性和完整性,并使用证书来验证服务器的身份。

证书包含了服务器的公钥和一些附加信息,由受信任的证书颁发机构(Certificate Authority,简称 CA)签发。当客户端与服务器建立连接时,服务器会将其证书发送给客户端,客户端通过验证证书的有效性和可信度来确保连接的安全性。

默认证书验证

在 Android 中,默认情况下,系统会对服务器证书进行验证。如果证书无效或不可信,系统将会抛出一个 SSLHandshakeException 异常。这种验证是必要的,以确保与服务器的通信是安全的。

下面是一个简单的示例代码,演示了如何通过 HTTPS 请求一个网页并打印返回结果:

public class MainActivity extends AppCompatActivity {
    private static final String URL = "

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL(URL);
                    HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
                    connection.connect();

                    InputStream inputStream = connection.getInputStream();
                    String result = readStream(inputStream);
                    Log.d("HTTPS", result);

                    connection.disconnect();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private String readStream(InputStream inputStream) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line;
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line);
        }
        reader.close();
        return stringBuilder.toString();
    }
}

这段代码会发出一个 HTTPS 请求,如果服务器的证书无效或不可信,代码将会抛出 SSLHandshakeException 异常。

信任所有证书

如果我们需要信任所有证书,可以通过自定义 TrustManager 来实现。

TrustManager 是一个接口,用于执行 SSL 证书验证。默认情况下,Android 使用 X509TrustManager 来验证证书。我们可以自定义一个实现了 X509TrustManager 的类,然后在 HttpsURLConnection 中使用该类来进行证书验证。

下面是一个示例代码,演示了如何设置信任所有证书:

public class MainActivity extends AppCompatActivity {
    private static final String URL = "

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL(URL);
                    HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

                    // 创建一个 TrustManager,信任所有证书
                    TrustManager[] trustAllCerts = new TrustManager[] {
                        new X509TrustManager() {
                            public void checkClientTrusted(X509Certificate[] chain, String authType) {}
                            public void checkServerTrusted(X509Certificate[] chain, String authType) {}
                            public X509Certificate[] getAcceptedIssuers() {
                                return new X509Certificate[0];
                            }
                        }
                    };

                    // 设置 TrustManager
                    SSLContext sslContext = SSLContext.getInstance("TLS");
                    sslContext.init(null, trustAllCerts, new SecureRandom());
                    connection.setSSLSocketFactory(sslContext.getSocketFactory());

                    connection.connect();

                    InputStream inputStream = connection.getInputStream();
                    String result = readStream(inputStream);
                    Log.d("HTTPS", result);

                    connection.disconnect();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    private String readStream(InputStream inputStream) throws IOException {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader