4. 抓包的原理
平常使用的抓包工具,无论是fidder和charles都能解析客户端和服务器的HTTPS数据,是如何做到的呢?其实抓包工具就充当了一个中间人代理的角色,参照2.https的工具原理,抓包的工作原理如下:
- 截获客户端向发起的HTTPS请求,佯装客户端,向真实的服务器发起请求
- 截获真实服务器的返回,佯装真实服务器,向客户端发送数据
- 获取了用来加密服务器公钥的非对称秘钥和用来加密数据的对称秘钥
5. Android 中使用 HTTPS以及如何防止抓包
Android中如何访问HTTPS呢,其实Retrofit、OkHttp均支持HTTPS的访问 项目中引入网络库,以**implementation ‘com.squareup.okhttp3:okhttp:4.2.0’**为例,
final OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
final Request request = new Request.Builder()
.url(“https://www.baidu.com/robots.txt”)
.build();
final Response execute = okHttpClient.newCall(request).execute();
final String bodyStr = execute.body().string();
Log.d(TAG, bodyStr);
那如果关闭客户端的CA证书,GlobalSign Root CA-R1,相当于不信任百度服务器的数字证书,会导致报错
Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
通过手动将GlobalSign Root CA-R1.cer
放入项目中的assets文件夹,则可避免这一错误,如何引用项目中集成的证书呢? 通过
SSLContext sslContext;
try {
InputStream inputStream = getAssets().open(“”);
sslContext = SSLContext.getInstance(“TLS”);
sslContext.init(null, new TrustManager[]{OkhttpU.trustManagerForCertificates(inputStream)}, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient okHttpClient = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory, OkhttpU.trustManagerForCertificates(inputStream)).build();
final Request request = new Request.Builder()
.url(“https://www.baidu.com/robots.txt”)
.build();
final Response execute = okHttpClient.newCall(request).execute();
final String bodyStr = execute.body().string();
Log.d(TAG, bodyStr);
} catch (Exception e) {
e.printStackTrace();
}
public class OkhttpU {
public static X509TrustManager trustManagerForCertificates(InputStream in)
throws GeneralSecurityException {
CertificateFactory certificateFactory = CertificateFactory.getInstance(“X.509”);
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
if (certificates.isEmpty()) {
throw new IllegalArgumentException(“expected non-empty set of trusted certificates”);
}
// Put the certificates a key store.
char[] password = “password”.toCharArray(); // Any password will work.
KeyStore keyStore = newEmptyKeyStore(password);
int index = 0;
for (Certificate certificate : certificates) {
String certificateAlias = Integer.toString(index++);
keyStore.setCertificateEntry(certificateAlias, certificate);
}
// Use it to build an X509 trust manager.
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, password);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException(“Unexpected default trust managers:”
- Arrays.toString(trustManagers));
}
return (X509TrustManager) trustManagers[0];
}
private static KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream in = null; // By convention, ‘null’ creates an empty key store.
keyStore.load(in, password);
return keyStore;
} catch (IOException e) {
throw new AssertionError(e);
}
}
}
就可以正常访问https了
综上,通过引入自定义证书,然后给OkHttp设置sslSocketFactory可以有效的防止抓包,但是.cer放到assets下很容易被反编译,可以通过jdk下的命令keytool -printcert -rfc -file srca.cer导出字符串,然后通过
OkHttpClientManager.getInstance()
.setCertificates(new Buffer()
.writeUtf8(CER_STRING) //CER_STRING是到处的string常量
.inputStream());
相关文章
文末
我总结了一些Android核心知识点,以及一些最新的大厂面试题、知识脑图和视频资料解析。
以后的路也希望我们能一起走下去。(谢谢大家一直以来的支持)
部分资料一览:
- 330页PDF Android学习核心笔记(内含8大板块)
-
Android学习的系统对应视频
-
Android进阶的系统对应学习资料
- Android BAT大厂面试题(有解析)
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!
中…(img-CjINmVDY-1715837465063)]
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!