在 Android 中,网络请求常常涉及到 HTTPS 访问,即采用了 SSL/TLS 加密传输数据的情况,为了保证安全性,Android 默认实现了证书校验机制。这意味着,当访问一个未知或无效 HTTPS 证书的网站时,Android 系统会给出警告提示,建议用户停止访问网站。但在一些特殊情况下,需要信任所有 HTTPS 证书,比如用于开发调试或测试等目的。本文将介绍如何在 Android 应用中信任所有 HTTPS 证书。
Android 中的 HTTPS 请求流程:
我们首先需要了解 Android 中 HTTPS 请求的工作原理。一般而言,HTTPS 请求流程如下所示:
1.客户端通过 HTTPS 发起请求;
2.服务器返回证书及公钥等相关信息;
3.客户端先校验证书的有效性,如果证书有效,则提取证书中的公钥,生成对称密钥(通常使用 AES 等算法),并使用公钥加密该对称密钥;接着,将加密后的对称密钥发送给服务器(这一过程被称作握手);
4.服务器使用私钥解密该对称密钥,并将数据通过对称密钥进行加密后返回客户端;
5.客户端使用该对称密钥进行解密,并得到返回的数据。
如何信任所有 HTTPS 证书:
针对 Android 中 HTTPS 请求流程中的证书校验步骤,我们可通过修改证书管理器(TrustManager)的实现方式来实现对所有 HTTPS 证书的信任。具体而言,我们需要通过实现 X509TrustManager 接口并重写其 checkClientTrusted 和 checkServerTrusted 方法,使其直接返回 true,在这种情况下,客户端将会信任所有 HTTPS 证书。示例代码如下:
```
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class TrustAllCerts implements X509TrustManager {
@Override
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] certs = new X509Certificate[0];
return certs;
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
// Do nothing, let them all in.
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
// Do nothing, let them all in.
}
}
```
上述代码中,我们先定义了一个 TrustAllCerts 类实现了 X509TrustManager 接口,并实现了其中的三个方法。其中,getAcceptedIssuers 方法应该返回一个 X509Certificate 数组,代表可信证书的列表。在所有证书都可信的情况下,该方法可以返回一个空列表。checkClientTrusted 和 checkServerTrusted 方法表示客户端和服务器之间的证书校验,当客户端通过这两个方法检验证书时均返回 true,表示信任所有 HTTPS 证书。
使用 trustworthy() 方法将信任所有证书的 TrustAllCerts 对象添加到 SSLContext 中:
```
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class HttpsUtils {
public static OkHttpClient getUnsafeOkHttpClient() {
try {
final TrustManager[] trustAllCerts = new TrustManager[] { new TrustAllCerts() };
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
final javax.net.ssl.SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
builder.hostnameVerifier((hostname, session) -> true);
return builder.build();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
```
上述代码中,我们先实例化了一个