这里是Bruno's answer的简洁版
public void configureTrustStore() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException,
CertificateException, IOException {
X509TrustManager jreTrustManager = getJreTrustManager();
X509TrustManager myTrustManager = getMyTrustManager();
X509TrustManager mergedTrustManager = createMergedTrustManager(jreTrustManager, myTrustManager);
setSystemTrustManager(mergedTrustManager);
}
private X509TrustManager getJreTrustManager() throws NoSuchAlgorithmException, KeyStoreException {
return findDefaultTrustManager(null);
}
private X509TrustManager getMyTrustManager() throws FileNotFoundException, KeyStoreException, IOException,
NoSuchAlgorithmException, CertificateException {
// Adapt to load your keystore
try (FileInputStream myKeys = new FileInputStream("truststore.jks")) {
KeyStore myTrustStore = KeyStore.getInstance("jks");
myTrustStore.load(myKeys, "password".toCharArray());
return findDefaultTrustManager(myTrustStore);
}
}
private X509TrustManager findDefaultTrustManager(KeyStore keyStore)
throws NoSuchAlgorithmException, KeyStoreException {
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore); // If keyStore is null, tmf will be initialized with the default trust store
for (TrustManager tm : tmf.getTrustManagers()) {
if (tm instanceof X509TrustManager) {
return (X509TrustManager) tm;
}
}
return null;
}
private X509TrustManager createMergedTrustManager(X509TrustManager jreTrustManager,
X509TrustManager customTrustManager) {
return new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
// If you're planning to use client-cert auth,
// merge results from "defaultTm" and "myTm".
return jreTrustManager.getAcceptedIssuers();
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
try {
customTrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException e) {
// This will throw another CertificateException if this fails too.
jreTrustManager.checkServerTrusted(chain, authType);
}
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
// If you're planning to use client-cert auth,
// do the same as checking the server.
jreTrustManager.checkClientTrusted(chain, authType);
}
};
}
private void setSystemTrustManager(X509TrustManager mergedTrustManager)
throws NoSuchAlgorithmException, KeyManagementException {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { mergedTrustManager }, null);
// You don't have to set this as the default context,
// it depends on the library you're using.
SSLContext.setDefault(sslContext);
}