在移动App的安全测试中,对HTTPS通信进行抓包是一项重要的工作。然而,许多App采取了证书校验等措施来防止被抓包。本文将介绍常见的HTTPS证书校验方式以及相应的对抗方法,并提供代码示例。
了解HTTPS证书
HTTPS通信中,使用非对称加密算法来协商通信的加密密钥,而HTTPS证书就是其中的一环,它实际上是公钥的载体。为了确保客户端接收到的证书的真实性,引入了CA(Certification Authority)机构,发布的证书称为CA证书。而为了防止CA证书被伪造,操作系统内置了一个信任库,保存了可信任的CA证书集合,用于校验服务端返回的证书的真实性。
证书校验实现&对抗
- 忽略证书校验
忽略证书校验是一种简单粗暴的方式,通过信任所有证书来实现。以下是一个使用OkHttp框架实现的示例:
// 忽略证书校验的请求示例
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(HttpsTrustAllCerts.createSSLSocketFactory(), new HttpsTrustAllCerts())
.hostnameVerifier(new HttpsTrustAllCerts.TrustAllHostnameVerifier())
.build();
Request request = new Request.Builder()
.url("https://www.example.com")
.build();
Response response = client.newCall(request).execute();
- 系统证书校验
默认情况下,OkHttp会使用系统信任库中的证书链对服务端返回的证书进行验证。以下是一个示例:
// 默认使用系统证书链校验
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://www.example.com")
.build();
Response response = client.newCall(request).execute();
- SSL Pinning(公钥绑定)
SSL Pinning是一种推荐的校验方式,通过在客户端预先设置好证书信息,与服务端返回的证书进行比较,以确保其真实性。以下是代码校验的示例:
// SSL Pinning代码校验示例
CertificatePinner certificatePinner = new CertificatePinner.Builder()
.add("www.example.com", "sha256/xxxxxxxxxxxxxx")
.build();
OkHttpClient client = new OkHttpClient.Builder()
.certificatePinner(certificatePinner)
.build();
Request request = new Request.Builder()
.url("https://www.example.com")
.build();
Response response = client.newCall(request).execute();
- 双向校验
双向校验是一种更加安全的方式,不仅客户端验证服务端证书,同时服务端也验证客户端证书。以下是一个示例:
// 双向校验示例
// 客户端配置
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(ClientSSLSocketFactory.getSocketFactory(context), trustManager)
.build();
// 服务端配置
server.socket = ssl.wrap_socket(server.socket, certfile = serverCerts, server_side = True,
keyfile = serverKey,
cert_reqs = ssl.CERT_REQUIRED,
ca_certs = clientCerts)
- WebView证书校验
WebView对HTTPS请求进行了封装,可以方便地进行证书校验。以下是一个示例:
// WebView证书校验示例
webView.setWebViewClient(new WebViewClient(){
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// 在此处进行证书校验
handler.cancel(); // 或者 handler.proceed();
}
});
- 代理检测
另一个常见的防抓包方法是通过检测代理来防止中间人攻击。以下是一个简单的示例:
// 检测代理示例
OkHttpClient client = new OkHttpClient.Builder()
.proxy(Proxy.NO_PROXY)
.build();
结语
本文详细介绍了HTTPS证书校验的常见方式以及相应的对抗方法,并提供了相应的代码示例。在实际应用中,需要根据具体情况选择合适的校验方式,并注意防范抓包等安全风险。