Es sieht aus wie eine Standardfrage, aber ich konnte nirgendwo klare Anweisungen finden.
Ich habe Java-Code, der versucht, eine Verbindung zu einem Server mit wahrscheinlich selbstsigniertem (oder abgelaufenem) Zertifikat herzustellen. Der Code meldet den folgenden Fehler:
[HttpMethodDirector] I/O exception (javax.net.ssl.SSLHandshakeException) caught
when processing request: sun.security.validator.ValidatorException: PKIX path
building failed: sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
So wie ich es verstehe, muss ich Keytool verwenden und Java mitteilen, dass es in Ordnung ist, diese Verbindung zuzulassen.
Alle Anweisungen zur Behebung dieses Problems setzen voraus, dass ich mit Keytool voll vertraut bin, wie z
Generieren Sie einen privaten Schlüssel für den Server und importieren Sie ihn in den Keystore
Gibt es jemanden, der detaillierte Anweisungen veröffentlichen könnte?
Ich verwende Unix, daher ist Bash-Skript am besten geeignet.
Ich bin mir nicht sicher, ob es wichtig ist, aber der Code wird in jboss ausgeführt.
Antworten:
Grundsätzlich haben Sie hier zwei Möglichkeiten: Fügen Sie das selbstsignierte Zertifikat zu Ihrem JVM-Truststore hinzu oder konfigurieren Sie Ihren Client für
Option 1
Exportieren Sie das Zertifikat aus Ihrem Browser und importieren Sie es in Ihren JVM-Truststore (um eine Vertrauenskette aufzubauen):
Option 2
Zertifikatvalidierung deaktivieren:
Beachten Sie, dass ich die Option 2 überhaupt nicht empfehle . Durch Deaktivieren des Vertrauensmanagers werden einige Teile von SSL besiegt und Sie sind anfällig für Man-in-the-Middle-Angriffe. Bevorzugen Sie Option 1 oder lassen Sie den Server ein "echtes" Zertifikat verwenden, das von einer bekannten Zertifizierungsstelle signiert wurde.
quelle
Ich habe dieses Problem an einen Zertifikatanbieter weitergeleitet, der ab sofort nicht mehr zu den standardmäßigen vertrauenswürdigen JVM-Hosts gehört
JDK 8u74
. Der Anbieter ist www.identrust.com , aber das war nicht die Domain, zu der ich eine Verbindung herstellen wollte. Diese Domain hatte ihr Zertifikat von diesem Anbieter erhalten. Siehe Wird das Cross-Root-Cover der Standardliste im JDK / JRE vertrauen? - Lesen Sie ein paar Einträge. Siehe auch Welche Browser und Betriebssysteme unterstützen Let's Encrypt .Um eine Verbindung zu der Domain herzustellen, an der ich interessiert war und von der ein Zertifikat ausgestellt wurde, habe
identrust.com
ich die folgenden Schritte ausgeführt. Grundsätzlich musste ich das identrust.com (DST Root CA X3
) -Zertifikat erhalten, um von der JVM als vertrauenswürdig eingestuft zu werden. Ich konnte das mit Apache HttpComponents 4.5 wie folgt machen:1: Beziehen Sie das Zertifikat von indettrust in den Anweisungen zum Herunterladen der Zertifikatskette . Klicken Sie auf den Link DST Root CA X3 .
2: Speichern Sie die Zeichenfolge in einer Datei mit dem Namen "DST Root CA X3.pem". Stellen Sie sicher, dass Sie die Zeilen "----- BEGIN CERTIFICATE -----" und "----- END CERTIFICATE -----" in die Datei am Anfang und am Ende einfügen.
3: Erstellen Sie eine Java-Keystore-Datei, cacerts.jks, mit dem folgenden Befehl:
4: Kopieren Sie den resultierenden Keystore cacerts.jks in das Ressourcenverzeichnis Ihrer Java / (Maven) -Anwendung.
5: Verwenden Sie den folgenden Code, um diese Datei zu laden und an den Apache 4.5 HttpClient anzuhängen. Dadurch wird das Problem für alle Domänen gelöst, für die Zertifikate von
indetrust.com
util oracle ausgestellt wurden, die das Zertifikat in den JRE-Standardschlüsselspeicher aufnehmen.Wenn das Projekt erstellt wird, werden die cacerts.jks in den Klassenpfad kopiert und von dort geladen. Ich habe zu diesem Zeitpunkt noch keine Tests mit anderen SSL-Sites durchgeführt, aber wenn der obige Code "Ketten" in diesem Zertifikat enthält, funktionieren sie auch, aber ich weiß es auch nicht.
Referenz: Benutzerdefinierter SSL-Kontext und Wie akzeptiere ich ein selbstsigniertes Zertifikat mit einer Java HttpsURLConnection?
quelle
Apache HttpClient 4.5 unterstützt das Akzeptieren selbstsignierter Zertifikate:
Dadurch wird eine SSL-Socket-Factory erstellt, die die verwendet
TrustSelfSignedStrategy
, es bei einem benutzerdefinierten Verbindungsmanager registriert und dann mit diesem Verbindungsmanager ein HTTP-GET ausführt.Ich stimme denen zu, die "dies in der Produktion nicht tun" singen, es gibt jedoch Anwendungsfälle für die Annahme selbstsignierter Zertifikate außerhalb der Produktion. Wir verwenden sie in automatisierten Integrationstests, sodass wir SSL (wie in der Produktion) verwenden, auch wenn es nicht auf der Produktionshardware ausgeführt wird.
quelle
Anstatt die Standard-Socket-Factory festzulegen (was IMO eine schlechte Sache ist), wirkt sich dies nur auf die aktuelle Verbindung aus und nicht auf jede SSL-Verbindung, die Sie öffnen möchten:
quelle
checkServerTrusted
implementieren nicht die erforderliche Logik, um dem Zertifikat tatsächlich zu vertrauen und sicherzustellen, dass nicht vertrauenswürdige Zertifikate abgelehnt werden. Dies könnte eine gute Lektüre sein: Der gefährlichste Code der Welt: Validieren von SSL-Zertifikaten in Nicht-Browser-Software .getAcceptedIssuers()
Methode entspricht nicht der Spezifikation, und diese "Lösung" bleibt radikal unsicher.Es gibt eine bessere Alternative zum Vertrauen in alle Zertifikate: Erstellen Sie ein Zertifikat
TrustStore
, das einem bestimmten Zertifikat spezifisch vertraut, und verwenden Sie dieses, um ein Zertifikat zu erstellen,SSLContext
von dem aus das ZertifikatSSLSocketFactory
festgelegt werden kannHttpsURLConnection
. Hier ist der vollständige Code:Alternativ können Sie das
KeyStore
Zertifikat direkt aus einer Datei laden oder das X.509-Zertifikat von einer vertrauenswürdigen Quelle abrufen.Beachten Sie, dass mit diesem Code die Zertifikate in
cacerts
nicht verwendet werden. DieseHttpsURLConnection
Person vertraut nur diesem bestimmten Zertifikat.quelle
Vertrauen Sie allen SSL-Zertifikaten: - Sie können SSL umgehen, wenn Sie auf dem Testserver testen möchten. Verwenden Sie diesen Code jedoch nicht für die Produktion.
}}
Rufen Sie diese Funktion in der Funktion onCreate () in Activity oder in Ihrer Anwendungsklasse auf.
Dies kann für Volley in Android verwendet werden.
quelle
Die akzeptierte Antwort ist in Ordnung, aber ich möchte etwas hinzufügen, da ich IntelliJ auf dem Mac verwendet habe und es mit der Pfadvariablen nicht zum Laufen bringen konnte
JAVA_HOME
.Es stellte sich heraus, dass Java Home beim Ausführen der Anwendung von IntelliJ anders war.
Um genau herauszufinden, wo es sich befindet, können Sie einfach
System.getProperty("java.home")
die vertrauenswürdigen Zertifikate lesen.quelle
Wenn 'sie' ein selbstsigniertes Zertifikat verwenden, liegt es an ihnen, die erforderlichen Schritte zu unternehmen, um ihren Server nutzbar zu machen. Konkret bedeutet dies, dass Sie das Zertifikat vertrauenswürdig offline bereitstellen. Lassen Sie sie das tun. Anschließend importieren Sie dies mithilfe des Keytools in Ihren Truststore, wie im JSSE-Referenzhandbuch beschrieben. Denken Sie nicht einmal an den unsicheren TrustManager, der hier veröffentlicht wurde.
BEARBEITEN Zum Nutzen der siebzehn (!) Downvoter und zahlreiche Kommentatoren unten, die offensichtlich nicht wirklich gelesen haben, was ich hier geschrieben habe, ist dies keine Jeremiade gegen selbstsignierte Zertifikate. Selbstsignierte Zertifikate sind bei korrekter Implementierung nicht falsch . Aber der richtige Weg , um sie zu implementieren , ist das Zertifikat haben geliefert sicher über einen Offline - Prozess, anstatt über den nicht - autorisierten Kanal sie verwendet wird , werden zu authentifizieren. Sicher ist das offensichtlich? Es ist für jede sicherheitsbewusste Organisation, für die ich jemals gearbeitet habe, offensichtlich, von Banken mit Tausenden von Filialen bis zu meinen eigenen Unternehmen. Die clientseitige Code-Basis-Lösung des Vertrauens allen zuZertifikate, einschließlich selbstsignierter Zertifikate, die von absolut jedem oder einer als Zertifizierungsstelle eingerichteten Schiedsstelle unterzeichnet wurden, sind ipso factonicht sicher. Es geht nur um Sicherheit. Es ist sinnlos. Sie führen ein privates, manipulationssicheres, antwort- und spritzwassergeschütztes Gespräch mit ... jemandem. Irgendjemand. Ein Mann in der Mitte. Ein Imitator. Irgendjemand. Sie können auch einfach Klartext verwenden.
quelle
Dies ist keine Lösung für das gesamte Problem, aber Oracle verfügt über eine ausführliche Dokumentation zur Verwendung dieses Keytools. Dies erklärt, wie es geht
https://docs.oracle.com/cd/E54932_01/doc.705/e54936/cssg_create_ssl_cert.htm#CSVSG178
quelle
Anstatt Keytool zu verwenden, wie im oberen Kommentar vorgeschlagen, können Sie in RHEL ab neueren Versionen von RHEL 6 update-ca-trust verwenden. Das Zertifikat muss im PEM-Format vorliegen. Dann
Bearbeiten Sie /etc/pki/ca-trust/source/cert.p11-kit und ändern Sie "Zertifikatskategorie: anderer Eintrag" in "Zertifikatskategorie: Autorität". (Oder verwenden Sie sed, um dies in einem Skript zu tun.) Dann tun Sie es
Ein paar Einschränkungen:
update-ca-trust enable
. Dadurch wird / etc / pki / java / cacerts durch einen symbolischen Link ersetzt, der auf / etc / pki / ca-trust / extrahiert / java / cacerts verweist. (Vielleicht möchten Sie zuerst die erste sichern.)quelle
Ich hatte das Problem, dass ich eine URL an eine Bibliothek
url.openConnection();
weitergab, die anrief. Ich passte Jon-Daniels Antwort an.Mit dieser Klasse ist es möglich, eine neue URL zu erstellen mit:
Dies hat den Vorteil, dass es lokalisiert ist und nicht die Standardeinstellung ersetzt
URL.openConnection
.quelle