Moja aplikacja ma osobisty magazyn kluczy zawierający zaufane certyfikaty z podpisem własnym do użytku w sieci lokalnej - na przykład mykeystore.jks
. Chcę mieć możliwość łączenia się z witrynami publicznymi (np. Google.com), a także z witrynami w mojej sieci lokalnej za pomocą certyfikatów z podpisem własnym, które zostały udostępnione lokalnie.Jak zainicjować TrustManagerFactory z wieloma źródłami zaufania?
Problemem tutaj jest to, że po podłączeniu do https://google.com, budowa ścieżki nie powiedzie się, ponieważ ustawienie własne kluczy przesłania domyślny kluczy zawierający głównych urzędów certyfikacji w pakiecie z JRE, zgłoszenie wyjątku
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Jednakże, jeśli Importuję certyfikat CA do mojego własnego magazynu kluczy (mykeystore.jks
), który działa poprawnie. Czy istnieje sposób na wsparcie obu?
mam własną TrustManger tym celu
public class CustomX509TrustManager implements X509TrustManager {
X509TrustManager defaultTrustManager;
public MyX509TrustManager(KeyStore keystore) {
TrustManagerFactory trustMgrFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustMgrFactory.init(keystore);
TrustManager trustManagers[] = trustMgrFactory.getTrustManagers();
for (int i = 0; i < trustManagers.length; i++) {
if (trustManagers[i] instanceof X509TrustManager) {
defaultTrustManager = (X509TrustManager) trustManagers[i];
return;
}
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
try {
defaultTrustManager.checkServerTrusted(chain, authType);
} catch (CertificateException ce) {
/* Handle untrusted certificates */
}
}
}
Następnie zainicjować SSLContext, TrustManager [] trustManagers = nowy TrustManager [] {nowy CustomX509TrustManager (kluczy)}; SSLContekst customSSLContext = SSLContext.getInstance ("TLS"); customSSLContext.init (null, trustManagers, null);
i ustawienia fabryczne gniazdo,
HttpsURLConnection.setDefaultSSLSocketFactory(customSSLContext.getSocketFactory());
Program główny,
URL targetServer = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) targetServer.openConnection();
Jeśli nie ustawić własne menedżerów Zaufanie, to łączy się https://google.com dobrze. Jak uzyskać "domyślny menedżer zaufania", który wskazuje na domyślny magazyn kluczy?
Możliwy duplikat [Rejestrowanie wielu magazynów kluczy w JVM] (http://stackoverflow.com/questions/1793979/registering-multiple-keystores-in-jvm) – OrangeDog