Implementing X509TrustManager - passing on part of the verification to existing verifier

后端 未结 2 966
北海茫月
北海茫月 2020-12-08 22:19

I need to ignore the PKIX path building exception

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException:
PKIX path building failed:          


        
2条回答
  •  生来不讨喜
    2020-12-08 22:39

    Instead of implementing X509TrustManager to trust any certificate, you can create a trust manager from the specific certificate in question. Load the certificate from a .p12 or .jks keystore or from a .crt-file (you can copy a certificate from the browser into a file, in Chrome by clicking the padlock and selecting Certificate). The code is shorter than implementing your own X509TrustManager:

    private static SSLSocketFactory createSSLSocketFactory(File crtFile) throws GeneralSecurityException, IOException {
        SSLContext sslContext = SSLContext.getInstance("SSL");
    
        // Create a new trust store, use getDefaultType for .jks files or "pkcs12" for .p12 files
        KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        // You can supply a FileInputStream to a .jks or .p12 file and the keystore password as an alternative to loading the crt file
        trustStore.load(null, null);
    
        // Read the certificate from disk
        X509Certificate result;
        try (InputStream input = new FileInputStream(crtFile)) {
            result = (X509Certificate) CertificateFactory.getInstance("X509").generateCertificate(input);
        }
        // Add it to the trust store
        trustStore.setCertificateEntry(crtFile.getName(), result);
    
        // Convert the trust store to trust managers
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(trustStore);
        TrustManager[] trustManagers = tmf.getTrustManagers();
    
        sslContext.init(null, trustManagers, null);
        return sslContext.getSocketFactory();
    }
    

    You can use it by calling HttpsURLConnection.setSSLSocketFactory(createSSLSocketFactory(crtFile)) (you probably want to initialize the socket factory once and reuse it, though).

提交回复
热议问题