Https的雙向認證

參考鏈接:https://www.cnblogs.com/blogs-of-lxl/p/10136582.html

鴻洋博客:https://blog.csdn.net/lmj623565791/article/details/48129405?utm_source=copy

public class HttpsUtils {
    public static class SSLParams {
        public SSLSocketFactory sSLSocketFactory;
        public X509TrustManager trustManager;
    }

    //    public static SSLParams getSslSocketFactory(InputStream[] certificates, InputStream bksFile, String password) {
    public static SSLParams getSslSocketFactory(InputStream certificates, InputStream bksFile, String password) {
        SSLParams sslParams = new SSLParams();
        try {
//            TrustManager[] trustManagers = prepareTrustManager(certificates);
            TrustManager[] trustManagers = prepareTrust(certificates);
            KeyManager[] keyManagers = prepareKeyManager(bksFile, password);
            SSLContext sslContext = SSLContext.getInstance("TLS");
            X509TrustManager trustManager = null;
            if (trustManagers != null) {
                trustManager = new MyTrustManager(chooseTrustManager(trustManagers));
            } else {
                trustManager = new UnSafeTrustManager();
            }
            sslContext.init(keyManagers, new TrustManager[]{trustManager}, null);
//            SSLSocketFactory NoSSLv3Factory = new NoSSLv3SocketFactory(sslContext.getSocketFactory());

            sslParams.sSLSocketFactory = sslContext.getSocketFactory();
            sslParams.trustManager = trustManager;
            return sslParams;
        } catch (NoSuchAlgorithmException e) {
            throw new AssertionError(e);
        } catch (KeyManagementException e) {
            throw new AssertionError(e);
        } catch (KeyStoreException e) {
            throw new AssertionError(e);
        }
    }

    private class UnSafeHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

    private static class UnSafeTrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new java.security.cert.X509Certificate[]{};
        }
    }

    private static TrustManager[] prepareTrustManager(InputStream... certificates) {
        if (certificates == null || certificates.length <= 0) return null;
        try {

            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
//            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            keyStore.load(null);
            int index = 0;
            for (InputStream certificate : certificates) {
                String certificateAlias = Integer.toString(index++);
                keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));
                try {
                    if (certificate != null)
                        certificate.close();
                } catch (IOException e) {
                }
            }
            TrustManagerFactory trustManagerFactory = null;

            trustManagerFactory = TrustManagerFactory.
                    getInstance(TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(keyStore);

            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();

            return trustManagers;
        }
//        catch (NoSuchAlgorithmException e) {
//            e.printStackTrace();
//        } catch (CertificateException e) {
//            e.printStackTrace();
//        } catch (KeyStoreException e) {
//            e.printStackTrace();
//        }
        catch (Exception e) {
//            FLog.e("prepareTrustManager failed " + e);
            FLog.e(e);
        }
        return null;

    }

    private static TrustManager[] prepareTrust(InputStream is) {
        Certificate ca;
        InputStream caInput = null;
        try {
            try {
                CertificateFactory cf = CertificateFactory.getInstance("X.509");
                caInput = new BufferedInputStream(is);
                ca = cf.generateCertificate(caInput);
                FLog.d("ca=" + ((X509Certificate) ca).getSubjectDN());


                // Create a KeyStore containing our trusted CAs
                String keyStoreType = KeyStore.getDefaultType();
                KeyStore keyStore = KeyStore.getInstance(keyStoreType);
//                KeyStore keyStore = KeyStore.getInstance("PKCS12");
                keyStore.load(null, null);
                keyStore.setCertificateEntry("ca", ca);

                // Create a TrustManager that trusts the CAs in our KeyStore
                String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
                TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
                tmf.init(keyStore);
                TrustManager[] trustManagers = tmf.getTrustManagers();

                return trustManagers;
            } catch (Exception e) {
                FLog.e(e);
            }

        } finally {
            if (caInput != null) {
                try {
                    caInput.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return null;

    }

    private static KeyManager[] prepareKeyManager(InputStream bksFile, String password) {
        try {
            if (bksFile == null || password == null) return null;
//            KeyStore clientKeyStore = KeyStore.getInstance("BKS");
            KeyStore clientKeyStore = KeyStore.getInstance("PKCS12");
            clientKeyStore.load(bksFile, password.toCharArray());

            FLog.d("clientKeyStore.getType()=" + clientKeyStore.getType());

            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(clientKeyStore, password.toCharArray());
            return keyManagerFactory.getKeyManagers();

        }
//        catch (KeyStoreException e) {
//            e.printStackTrace();
//        } catch (NoSuchAlgorithmException e) {
//            e.printStackTrace();
//        } catch (UnrecoverableKeyException e) {
//            e.printStackTrace();
//        } catch (CertificateException e) {
//            e.printStackTrace();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
        catch (Exception e) {
//            FLog.e("prepareKeyManager failed " + e);
            FLog.e(e);
        }
        return null;
    }

    private static X509TrustManager chooseTrustManager(TrustManager[] trustManagers) {
        for (TrustManager trustManager : trustManagers) {
            if (trustManager instanceof X509TrustManager) {
                return (X509TrustManager) trustManager;
            }
        }
        return null;
    }


    private static class MyTrustManager implements X509TrustManager {
        private X509TrustManager defaultTrustManager;
        private X509TrustManager localTrustManager;

        public MyTrustManager(X509TrustManager localTrustManager) throws NoSuchAlgorithmException, KeyStoreException {
            TrustManagerFactory var4 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
            var4.init((KeyStore) null);
            defaultTrustManager = chooseTrustManager(var4.getTrustManagers());
            this.localTrustManager = localTrustManager;
        }


        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            try {
                defaultTrustManager.checkServerTrusted(chain, authType);
            } catch (CertificateException ce) {
                localTrustManager.checkServerTrusted(chain, authType);
            }
        }


        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }
}

    private final static String CLIENT_BKS_PASSWORD = "123456";//私鑰密碼
    private String clientKeyStoreFile = "/backup/certs/me7-hu.jks";
    private String clientTrustKeyStoreFile = "/backup/certs/me7-p0-p1.cer";


  private OkHttpClient providerHttpClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();

        InputStream keysIn = null;
//        InputStream[] trustIn = new InputStream[4];
        InputStream trustIn = null;

        try {
//            keysIn = getAppContext().getAssets().open(CLIENT_PRI_KEY);//加載客戶端私鑰
//            trustIn[0] = getAppContext().getAssets().open(TRUSTSTORE_PUB_KEY);//加載證書
            keysIn = new BufferedInputStream(new FileInputStream(clientKeyStoreFile));//加載客戶端私鑰
//            trustIn[0] = new FileInputStream(clientTrustKeyStoreFile);//加載證書
            trustIn = new BufferedInputStream(new FileInputStream(clientTrustKeyStoreFile));//加載證書
        } catch (IOException e) {
            FLog.e("certification OnError", e);
        }

//        if (trustIn != null && trustIn.length > 0 && keysIn != null) {
        if (trustIn != null && keysIn != null) {
            FLog.d("certification is exist");
            //證書的inputstream,本地證書的inputstream, 本地證書的密碼
            HttpsUtils.SSLParams sslParams = HttpsUtils.getSslSocketFactory(
                    trustIn,
                    keysIn,
                    CLIENT_BKS_PASSWORD);
            builder.sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager);
        } else {
            FLog.d("certification is null");
            AllTrustManager trustManager = new AllTrustManager();
            builder.sslSocketFactory(providerSSLSocketFactory(trustManager), trustManager);
        }
        builder
                .hostnameVerifier((hostname, session) -> true)
                .connectTimeout(mBuilder.mConnectTimeout, TimeUnit.MILLISECONDS)
                .readTimeout(mBuilder.mReadTimeout, TimeUnit.MILLISECONDS)
                .writeTimeout(mBuilder.mWriteTimeout, TimeUnit.MILLISECONDS);

        if (mBuilder.mHttpLog) {
            HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(
                    message -> FLog.i("HttpLog", message));
            loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            builder.addInterceptor(loggingInterceptor);
        }
        //刷新token
        builder.addInterceptor(new AuthenticatorInterceptor(mBuilder.mBaseUrl));
        return builder.build();
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章