Wie kann ich die initialisieren eines TrustManagerFactory mit mehreren Quellen von Vertrauen?
Meine Anwendung hat eine persönliche vertrauenswürdigen Schlüsselspeicher selbst-signierte Zertifikate für die Nutzung im lokalen Netz - sagen mykeystore.jks
. Ich möchte in der Lage sein, eine Verbindung zu öffentlichen Webseiten(sagen google.com) sowie diejenigen, die in meinem lokalen Netzwerk, die selbstsignierte Zertifikate verwenden, die bereitgestellt wurden, lokal.
Das problem hier ist, dass, wenn ich eine Verbindung zu https://google.com, Weg Gebäude schlägt fehl, da die Einstellung meiner eigenen keystore überschreibt die Standard-keystore mit root-CAs zusammen mit der JRE, die Berichterstattung über die Ausnahme
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Allerdings, wenn ich importieren Sie ein CA-Zertifikat in meinem eigenen keystore(mykeystore.jks
) funktioniert es einwandfrei. Gibt es eine Möglichkeit diese beiden zu unterstützen?
Habe ich meine eigene TrustManger für diesen Zweck,
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 */
}
}
}
Ich dann die Initialisierung des SSLContext,
TrustManager[] trustManagers =
new TrustManager[] { new CustomX509TrustManager(keystore) };
SSLContext customSSLContext =
SSLContext.getInstance("TLS");
customSSLContext.init(null, trustManagers, null);
und legen Sie die socket factory,
HttpsURLConnection.setDefaultSSLSocketFactory(customSSLContext.getSocketFactory());
Hauptprogramm,
URL targetServer = new URL(url);
HttpsURLConnection conn = (HttpsURLConnection) targetServer.openConnection();
Wenn ich nicht mein eigenes Vertrauen, Führungskräfte, verbindet es sich mit https://google.com gut. Wie bekomme ich eine "Standard-trust-manager", die Punkte auf dem Standard-Schlüssel speichern?
- Mögliche Duplikate von Registrieren von mehreren JVM-Schlüsselspeicher in
Du musst angemeldet sein, um einen Kommentar abzugeben.
In
trustMgrFactory.init(keystore);
Sie konfigurieren defaultTrustManager mit Ihrem persönlichen keystore, nicht den Standard-system-keystore.Basierend auf dem Lesen der Quell-code für die Sonne.Sicherheit.ssl.TrustManagerFactoryImpl, es sieht aus wie
trustMgrFactory.init((KeyStore) null);
würde genau das tun, was Sie brauchen (laden Sie die system-Standard-keystore), und basiert auf eine schnelle Prüfung, es scheint zu funktionieren für mich.openjdk version "1.8.0_151"
Die Antwort hier ist, wie ich kam, um zu verstehen, wie dies zu tun. Wenn Sie nur wollen, zu akzeptieren, das system-CA-CERT plus einem benutzerdefinierten Schlüsselspeicher des certs ich es vereinfacht in einer einzigen Klasse mit einigen convenience-Methoden. Vollständigen code finden Sie hier:
https://gist.github.com/HughJeffner/6eac419b18c6001aeadb
Ich habe laufen in das gleiche Problem mit Commons HttpClient. Funktionierende Lösung für meinen Fall war das erstellen delegationskette für PKIX TrustManagers in folgender Weise:
Und initialisieren HttpClient in der folgenden Weise (ja es ist hässlich):
In Ihrem Fall mit einfachen HttpsURLConnection, die Sie eventuell erhalten, indem Sie mit der vereinfachten version der delegierenden Klasse:
Für Android-Entwickler, können Sie dies viel einfacher. In Zusammenfassung, können Sie ein xml-res-Datei config Ihrem benutzerdefinierten certs.
Schritt 1: öffnen Sie die xml-Manifestdatei ein Attribut hinzuzufügen.
Schritt 2: Hinzufügen network_security_config.xml zu res/xml, config certs, wie Sie wollen.
Hinweis: diese xml unterstützen können, viele andere Verwendung, und diese Lösung funktioniert nur auf api24+.
Offizielle Referenz: hier