Okhttp 자가 서명된 여러 인증서 HTTPS 주소 솔루션 액세스

4505 단어
우선 Okhttp 자가 서명 인증서 HTTPS 주소 해결 방안 위의 이 블로그를 참고하여 자가 서명 인증서에 접근하는 문제를 해결하였습니다.그러나 때때로 우리는 도메인을 너무 많이 방문해야 한다. 도메인마다 인증서가 다르기 때문에 우리는 어떻게 해야 하는가?
public class HttpsUtils {

    private MyTrustManager mMyTrustManager;

    private SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory ssfFactory = null;
        try {
            mMyTrustManager = new MyTrustManager();
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{mMyTrustManager}, new SecureRandom());
            ssfFactory = sc.getSocketFactory();
        } catch (Exception ignored) {
            ignored.printStackTrace();
        }

        return ssfFactory;
    }

    //  X509TrustManager  
    public class MyTrustManager 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 X509Certificate[0];
        }
    }

    //  HostnameVerifier  
    private class TrustAllHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
   
    /**
     *          trustManager
     *
     * @param ins        
     * @return        trustManager
     * @throws GeneralSecurityException
     */
    private X509TrustManager trustManagerForCertificates(InputStream...ins)
            throws GeneralSecurityException {
        //      
        CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");

        //                
        Collection< Certificate> certificates=new ArrayList<>();

        for(InputStream inputStream:ins) {
            certificates.addAll(certificateFactory.generateCertificates(inputStream));
        }

        if (certificates.isEmpty()) {
            throw new IllegalArgumentException("expected non-empty set of trusted certificates");
        }

        //       keyStore
        char[] password = "password".toCharArray(); // Any password will work.
        KeyStore keyStore = newEmptyKeyStore(password);
        int index = 0;
        //           keystore 
        for (Certificate certificate : certificates) {
            String certificateAlias = Integer.toString(index++);
            keyStore.setCertificateEntry(certificateAlias, certificate);
        }


        // Use it to build an X509 trust manager.
        //           keyStore     X509TrustManager
        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 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(null, password);
            return keyStore;
        } catch (IOException e) {
            throw new AssertionError(e);
        }
    }
}


trustManagerForCertificates.(InputStream...ins) 인증서의 입력 흐름입니다. 예를 들어 인증서 파일은 두 개입니다.crt와 2.crt
Object[] sSlSocketFactoryParams=trustManagerForCertificates(new InputFileStream(new File("1.crt"),new FileInputStream("2.crt")))
//   SSLSocketFactory X509TrustManager
 OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .sslSocketFactory((SSLSocketFactory) sSlSocketFactoryParams[0], (X509TrustManager) sSlSocketFactoryParams[1])
                .build();

좋은 웹페이지 즐겨찾기