使用環境:
1 不願項目數據外泄使用了https,
2 講cer證書轉換成了bks文件,並存放只assets文件下
3
if ( 聯網方法不是retrofit 2.0 以上){
return;
}
其他沒什麼限制,這篇也就是特例特講。
使用方法:
OkHttpClient sOkHttpClient = new OkHttpClient.Builder()
.cookieJar(new CookieJarImpl(new PersistentCookieStore(Utils.getContext())))
.addInterceptor(new BaseInterceptor(headers))
.addInterceptor(new CacheInterceptor(Utils.getContext()))
.addInterceptor(new LoggingInterceptor
.Builder()//構建者模式
.loggable(BuildConfig.DEBUG) //是否開啓日誌打印
.setLevel(Level.BASIC) //打印的等級
.log(Platform.INFO) // 打印類型
.request("Request") // request的Tag
.response("Response")// Response的Tag
.addHeader("log-header", "I am the log request header.") // 添加打印頭, 注意 key 和 value 都不能是中文
.build()
)
.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.writeTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.readTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool(3, 2, TimeUnit.MINUTES))
.build();
HostnameVerifier hv1 = new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
//通過反射拿到okhttpClient 對象,給sslParams的SSLSocketFactory賦值
String workerClassName = "okhttp3.OkHttpClient";
try {
Class workerClass = Class.forName(workerClassName);
Field hostnameVerifier = workerClass.getDeclaredField("hostnameVerifier");
hostnameVerifier.setAccessible(true);
hostnameVerifier.set(sOkHttpClient, hv1);
Field sslSocketFactory = workerClass.getDeclaredField("sslSocketFactory");
sslSocketFactory.setAccessible(true);
//主要就是這一步
//utils.getContext() 就是當前上下文對象
//SSLSocketFactoryUtils代碼在下面 sslSocketFactory.set(sOkHttpClient,SSLSocketFactoryUtils.getSSLSocketFactory(Utils.getContext()));
} catch (Exception e) {
e.printStackTrace();
}
retrofit = new Retrofit.Builder()
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.baseUrl(url)
.client(sOkHttpClient)
.build();
SSLSocketFactoryUtils代碼:
public class SSLSocketFactoryUtils {
/**
* 獲取bks文件的sslsocketfactory
*
* @param context
* @return
*/
public static SSLSocketFactory getSSLSocketFactory(Context context) {
final String CLIENT_TRUST_PASSWORD = "123456";//信任證書密碼,該證書默認密碼是123456
final String CLIENT_AGREEMENT = "TLS";//使用協議
final String CLIENT_TRUST_KEYSTORE = "BKS";
SSLContext sslContext = null;
try {
//取得SSL的SSLContext實例
sslContext = SSLContext.getInstance(CLIENT_AGREEMENT);
//取得TrustManagerFactory的X509密鑰管理器實例
TrustManagerFactory trustManager = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
//取得BKS密庫實例
KeyStore tks = KeyStore.getInstance(CLIENT_TRUST_KEYSTORE);
InputStream is = context.getResources().openRawResource(R.raw.shiqin);
try {
tks.load(is, CLIENT_TRUST_PASSWORD.toCharArray());
} finally {
is.close();
}
//初始化密鑰管理器
trustManager.init(tks);
//初始化SSLContext
sslContext.init(null, trustManager.getTrustManagers(), null);
LogUtils.e("攜帶證書發送請求");
} catch (Exception e) {
e.printStackTrace();
LogUtils.e("證書解析出問題");
Log.e("SslContextFactory-->", e.getMessage());
}
return sslContext.getSocketFactory();
}
}
集成報錯:
Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:229)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:319)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:283)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:168)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.kjq.common.utils.network.http.interceptor.logging.LoggingInterceptor.intercept(LoggingInterceptor.java:75)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.kjq.common.utils.network.http.interceptor.CacheInterceptor.intercept(CacheInterceptor.java:31)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.kjq.common.utils.network.http.interceptor.BaseInterceptor.intercept(BaseInterceptor.java:32)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at okhttp3.RealCall.execute(RealCall.java:92)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at retrofit2.OkHttpCall.execute(OkHttpCall.java:180)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:42)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at io.reactivex.Observable.subscribe(Observable.java:12246)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at io.reactivex.Observable.subscribe(Observable.java:12246)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
2020-06-18 12:46:51.004 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at java.lang.Thread.run(Thread.java:764)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.TrustManagerImpl.verifyChain(TrustManagerImpl.java:661)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:539)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.TrustManagerImpl.checkTrustedRecursive(TrustManagerImpl.java:605)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:495)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:418)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.TrustManagerImpl.getTrustedChainForServer(TrustManagerImpl.java:339)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at android.security.net.config.NetworkSecurityTrustManager.checkServerTrusted(NetworkSecurityTrustManager.java:94)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at android.security.net.config.RootTrustManager.checkServerTrusted(RootTrustManager.java:88)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.Platform.checkServerTrusted(Platform.java:208)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.ConscryptFileDescriptorSocket.verifyCertificateChain(ConscryptFileDescriptorSocket.java:404)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.NativeSsl.doHandshake(NativeSsl.java:375)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: at com.android.org.conscrypt.ConscryptFileDescriptorSocket.startHandshake(ConscryptFileDescriptorSocket.java:224)
2020-06-18 12:46:51.005 31586-31586/com.fanfareknowledge.pickupkinsfolk W/System.err: ... 42 more
是的,就是這個報錯:SSLHandshakeException
自此開始百度:
https://www.jianshu.com/p/64172ccfb73b
https://www.jianshu.com/p/995c0c7c8875
……
很多,但依然無效。
偶然一片博客指出retrofit 2.0以上,重寫SSLContext的SSLSocketFactory 和TrustManager是無效的,
只能通過反射原理是retrofit默認信任全部證書。
至此,降低了retorfit的版本爲1.9,在這個基礎上使用其他常規的方法重寫SSLSocketFactory就可以實現抓包時抓不到聯網交互數據。
常規防範很多,retrofit 2.0版本也更新了不少東西,相比較以前更好用了很多。希望有關於retrofit2.0以上版本的cer證書配置方法更早接觸…
更多討論歡迎來詢: 88627109