How do I initialize a TrustManagerFactory with multiple sources of trust?

后端 未结 6 1432
伪装坚强ぢ
伪装坚强ぢ 2020-12-25 15:42

My application has a personal keystore containing trusted self-signed certificates for use in the local network - say mykeystore.jks. I wish to be able to conne

6条回答
  •  情深已故
    2020-12-25 16:04

    import com.google.common.collect.ImmutableList;
    import com.google.common.collect.Iterables;
    
    import java.security.KeyStore;
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import java.util.Arrays;
    import java.util.List;
    
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.TrustManagerFactory;
    import javax.net.ssl.X509TrustManager;
    
    /**
     * Represents an ordered list of {@link X509TrustManager}s with additive trust. If any one of the composed managers
     * trusts a certificate chain, then it is trusted by the composite manager.
     *
     * This is necessary because of the fine-print on {@link SSLContext#init}: Only the first instance of a particular key
     * and/or trust manager implementation type in the array is used. (For example, only the first
     * javax.net.ssl.X509KeyManager in the array will be used.)
     *
     * @author codyaray
     * @since 4/22/2013
     * @see 
     *     http://stackoverflow.com/questions/1793979/registering-multiple-keystores-in-jvm
     *     
     */
    @SuppressWarnings("unused")
    public class CompositeX509TrustManager implements X509TrustManager {
    
        private final List trustManagers;
    
        public CompositeX509TrustManager(List trustManagers) {
            this.trustManagers = ImmutableList.copyOf(trustManagers);
        }
    
        public CompositeX509TrustManager(KeyStore keystore) {
    
            this.trustManagers = ImmutableList.of(getDefaultTrustManager(), getTrustManager(keystore));
    
        }
    
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            for (X509TrustManager trustManager : trustManagers) {
                try {
                    trustManager.checkClientTrusted(chain, authType);
                    return; // someone trusts them. success!
                } catch (CertificateException e) {
                    // maybe someone else will trust them
                }
            }
            throw new CertificateException("None of the TrustManagers trust this certificate chain");
        }
    
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            for (X509TrustManager trustManager : trustManagers) {
                try {
                    trustManager.checkServerTrusted(chain, authType);
                    return; // someone trusts them. success!
                } catch (CertificateException e) {
                    // maybe someone else will trust them
                }
            }
            throw new CertificateException("None of the TrustManagers trust this certificate chain");
        }
    
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            ImmutableList.Builder certificates = ImmutableList.builder();
            for (X509TrustManager trustManager : trustManagers) {
                for (X509Certificate cert : trustManager.getAcceptedIssuers()) {
                    certificates.add(cert);
                }
            }
            return Iterables.toArray(certificates.build(), X509Certificate.class);
        }
    
        public static TrustManager[] getTrustManagers(KeyStore keyStore) {
    
            return new TrustManager[] { new CompositeX509TrustManager(keyStore) };
    
        }
    
        public static X509TrustManager getDefaultTrustManager() {
    
            return getTrustManager(null);
    
        }
    
        public static X509TrustManager getTrustManager(KeyStore keystore) {
    
            return getTrustManager(TrustManagerFactory.getDefaultAlgorithm(), keystore);
    
        }
    
        public static X509TrustManager getTrustManager(String algorithm, KeyStore keystore) {
    
            TrustManagerFactory factory;
    
            try {
                factory = TrustManagerFactory.getInstance(algorithm);
                factory.init(keystore);
                return Iterables.getFirst(Iterables.filter(
                        Arrays.asList(factory.getTrustManagers()), X509TrustManager.class), null);
            } catch (NoSuchAlgorithmException | KeyStoreException e) {
                e.printStackTrace();
            }
    
            return null;
    
        }
    
    }
    

提交回复
热议问题