android Retrofit 配置https證書

使用環境:

       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

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章