1. 程式人生 > >Retrofit2 配置雙向https認證

Retrofit2 配置雙向https認證

1 .運維工程師從阿里雲匯出的證書.

伺服器端證書


客戶端證書


2.轉換證書

伺服器端證書裡我們需要214410367490223.pfx,pfx型別的證書是攜帶私鑰的,我們需要轉換成cer型別把私鑰刪除.




到這裡伺服器端的證書就轉換完成了.

因為給的客戶端證書裡有我們需要的格式(client.p12),所以就不要轉換了.

3.把server.bks和client.p12放到專案的assets目錄下

4.程式碼設定

public class SSL {

    private final static String SERVER_PFX_PASSWORD = "214410367490223";
    private final static String CLIENT_P12_PASSWORD = "koAe5h8F";

    public static SSLSocketFactory getSSLSocketFactory(Context context) {

        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("TLS");
            sslContext.init(getKeyManagerFactory(context).getKeyManagers(), getTrustManagerFactory(context).getTrustManagers(), null);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        return sslContext != null ? sslContext.getSocketFactory() : null;
    }

    /**
     *client端
     * @param context
     * @return
     */
    public static KeyManagerFactory getKeyManagerFactory(Context context){
        KeyStore keyStore = null;
        KeyManagerFactory keyManagerFactory = null;
        try {
            keyStore = KeyStore.getInstance("PKCS12");
            InputStream ksIn = context.getAssets().open("client.p12");
            keyStore.load(ksIn, CLIENT_P12_PASSWORD.toCharArray());
            ksIn.close();
            keyManagerFactory = KeyManagerFactory.getInstance("X509");
            keyManagerFactory.init(keyStore, CLIENT_P12_PASSWORD.toCharArray());
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return keyManagerFactory;
    }

    /**
     *server端
     * @param context
     * @return
     */
    public static TrustManagerFactory getTrustManagerFactory(Context context){
        KeyStore trustStore = null;
        TrustManagerFactory trustManagerFactory = null;
        try {
            trustStore = KeyStore.getInstance("bks");
            InputStream tsIn = context.getAssets().open("server.bks");
            trustStore.load(tsIn, SERVER_PFX_PASSWORD.toCharArray());
            trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trustStore);
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return trustManagerFactory;
    }
}
            OkHttpClient okHttpClient = new OkHttpClient.Builder()
                    .readTimeout(31000, TimeUnit.MILLISECONDS)
                    .connectTimeout(31000, TimeUnit.MILLISECONDS)
                    .addInterceptor(interceptor)//增加這個會導致CountingRequestBody執行兩次
                    .addInterceptor(new MInterceptor())
                    .cache(cache)
                    .build();


這時候請把域名前面改成https.