Ich habe heute ein Upgrade von Java 1.6 auf Java 1.7 durchgeführt. Seitdem tritt ein Fehler auf, wenn ich versuche, über SSL eine Verbindung zu meinem Webserver herzustellen:
javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name
at sun.security.ssl.ClientHandshaker.handshakeAlert(ClientHandshaker.java:1288)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1904)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1027)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1262)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1289)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1273)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:523)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1296)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at java.net.URL.openStream(URL.java:1035)
Hier ist der Code:
SAXBuilder builder = new SAXBuilder();
Document document = null;
try {
url = new URL(https://some url);
document = (Document) builder.build(url.openStream());
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(DownloadLoadiciousComputer.class.getName()).log(Level.SEVERE, null, ex);
}
Es ist nur ein Testprojekt, deshalb erlaube und verwende ich nicht vertrauenswürdige Zertifikate mit dem Code:
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
Logger.getLogger(DownloadManager.class.getName()).log(Level.SEVERE, null, e);
}
Ich habe erfolgreich versucht, eine Verbindung zu https://google.com herzustellen . Wo ist meine Schuld?
Vielen Dank.
Ich hatte das, was ich glaube, das gleiche Problem. Ich stellte fest, dass ich die Apache-Konfiguration anpassen musste, um einen Servernamen oder ServerAlias für den Host einzuschließen.
Dieser Code ist fehlgeschlagen:
Und dieser Code hat funktioniert:
Wireshark gab bekannt, dass während des TSL / SSL-Hallo die Warnmeldung (Stufe: Warnung, Beschreibung: Nicht erkannter Name), Server Hallo vom Server an den Client gesendet wurde. Es war jedoch nur eine Warnung. Java 7.1 antwortete dann sofort mit einer "Schwerwiegenden, Beschreibung: Unerwartete Nachricht". Ich gehe davon aus, dass die Java-SSL-Bibliotheken die Warnung vor nicht erkannten Namen nicht gerne sehen.
Aus dem Wiki zur Transport Layer Security (TLS):
112 Nicht erkannte Namenswarnung Nur TLS; Der Servername-Indikator des Clients hat einen Hostnamen angegeben, der vom Server nicht unterstützt wird
Dies führte mich zu einem Blick auf meine Apache-Konfigurationsdateien und ich stellte fest, dass das Hinzufügen eines Servernamens oder ServerAlias für den von der Client- / Java-Seite gesendeten Namen ohne Fehler ordnungsgemäß funktionierte.
quelle
ServerAlias
hat für mich funktioniert. Ich hatte den gleichen TLS-Alarm in Wireshark gesehen.ServerName
Sekunden verwenden, antwortet Apache mit einerunrecognized_name
Warnmeldung (die auch eine schwerwiegende Warnung sein kann). RFC 6066 sagt dies genau zu diesem Thema: " Es wird NICHT EMPFOHLEN, eine Warnung für nicht erkannten Warennamen (112) auf Warnungsebene zu senden, da das Verhalten des Clients als Reaktion auf Warnungen auf Warnungsebene nicht vorhersehbar ist. " Der einzige Fehler, den dieser Mitarbeiter gemacht hat, ist die Annahme, dass dies eine fatale Warnung war. Dies ist sowohl ein JRE-Fehler als auch ein Apache-Fehler.Sie können das Senden von SNI-Datensätzen mit der Systemeigenschaft jsse.enableSNIExtension = false deaktivieren.
Wenn Sie den Code ändern können, ist die Verwendung hilfreich
SSLCocketFactory#createSocket()
(ohne Host-Parameter oder mit angeschlossenem Socket). In diesem Fall wird keine Angabe des Servernamens gesendet.quelle
System.setProperty ("jsse.enableSNIExtension", "false");
-Djsse.enableSNIExtension=false
. Aber was macht es sonst noch? Ist es schädlich für den Rest der Sicherheit von Javas?Dieser Fehler ist auch bei einem neuen Apache-Server-Build aufgetreten.
In unserem Fall bestand die Lösung darin, ein
ServerAlias
in dem zu definierenhttpd.conf
, das dem Hostnamen entsprach, zu dem Java eine Verbindung herstellen wollte. UnserServerName
wurde auf den internen Hostnamen gesetzt. Unser SSL-Zertifikat verwendete den externen Hostnamen, aber das reichte nicht aus, um die Warnung zu vermeiden.Um das Debuggen zu erleichtern, können Sie diesen ssl-Befehl verwenden:
openssl s_client -servername <hostname> -connect <hostname>:443 -state
Wenn es ein Problem mit diesem Hostnamen gibt, wird diese Nachricht oben in der Ausgabe gedruckt:
SSL3 alert read: warning:unrecognized name
Ich sollte auch beachten, dass wir diesen Fehler nicht erhalten haben, als wir diesen Befehl zum Herstellen einer Verbindung mit dem internen Hostnamen verwendet haben, obwohl er nicht mit dem SSL-Zertifikat übereinstimmt.
quelle
openssl
. Es ist sehr hilfreich.SSL3 alert read: warning:unrecognized name
? Ich sehe die Warnung gedruckt, aber die Ausgabe hilft mir nicht, diesenOpenSSL 1.0.1e-fips 11 Feb 2013
,OpenSSL 1.0.2k-fips 26 Jan 2017
undLibreSSL 2.6.5
.Anstatt sich auf den Standardmechanismus für virtuelle Hosts in Apache zu verlassen, können Sie einen letzten virtuellen Catchall-Host definieren, der einen beliebigen Servernamen und einen Platzhalter ServerAlias verwendet, z
Auf diese Weise können Sie SNI verwenden und Apache sendet die SSL-Warnung nicht zurück.
Dies funktioniert natürlich nur, wenn Sie alle Ihre Domänen einfach mit einer Platzhalter-Syntax beschreiben können.
quelle
*.mydomain.com
Platzhalterzertifikat verfügen, geben Sie entweder alle verwendeten Unterdomänen an oder verwenden Sie die Syntax für ServerAlias. Beachten Sie, dass Sie mehrere Aliase hinzufügen könnenServerAlias
, zServerAlias *.mydomain.com mydomain.com *.myotherdomain.com
.Es sollte nützlich sein. So versuchen Sie einen SNI-Fehler in Apache HttpClient 4.4 erneut - der einfachste Weg, den wir gefunden haben (siehe HTTPCLIENT-1522 ):
und
und
quelle
verifyHostname(sslsock, target)
inSSLConnectionSocketFactory.createLayeredSocket
? Da dietarget
Zeichenfolge in eine leere Zeichenfolge geändert wird,verifyHostname
wird dies nicht erfolgreich sein. Vermisse ich hier etwas Offensichtliches?Verwenden:
quelle
Ist auf dieses Problem mit Spring Boot und JVM 1.7 und 1.8 gestoßen. In AWS hatten wir nicht die Möglichkeit, den Servernamen und die ServerAlias so zu ändern, dass sie übereinstimmen (sie sind unterschiedlich). Daher haben wir Folgendes getan:
In build.gradle haben wir Folgendes hinzugefügt:
Dadurch konnten wir das Problem mit dem "nicht erkannten Namen" umgehen.
quelle
Sie können dem Tool jarsigner.exe leider keine Systemeigenschaften zuweisen.
Ich habe den Fehler 7177232 eingereicht, auf den Fehler 7127374 von @eckes verwiesen und erklärt, warum er fälschlicherweise geschlossen wurde.
Bei meinem Fehler geht es speziell um die Auswirkungen auf das Jarsigner-Tool, aber möglicherweise führt dies dazu, dass der andere Fehler erneut geöffnet und das Problem ordnungsgemäß behoben wird.
UPDATE: Es stellt sich heraus, dass Sie dem Jarsigner-Tool Systemeigenschaften bereitstellen können. Dies ist nur nicht in der Hilfemeldung enthalten. Verwenden
jarsigner -J-Djsse.enableSNIExtension=false
quelle
Ich habe das gleiche Problem festgestellt und es stellte sich heraus, dass Reverse DNS nicht korrekt eingerichtet war. Es zeigte auf einen falschen Hostnamen für die IP. Nachdem ich Reverse DNS korrigiert und httpd neu gestartet habe, ist die Warnung verschwunden. (Wenn ich Reverse-DNS nicht korrigiere, hat das Hinzufügen von ServerName auch für mich geholfen)
quelle
Mein
VirtualHost
'sServerName
wurde standardmäßig auskommentiert. Es funktionierte nach dem Kommentieren.quelle
Wenn Sie einen Client mit Resttemplate erstellen, können Sie den Endpunkt nur wie folgt festlegen : https: // IP / path_to_service und die requestFactory festlegen.
Mit dieser Lösung müssen Sie TOMCAT oder Apache nicht neu starten:
quelle
Ich bin auch auf dieses Problem beim Upgrade von Java 1.6_29 auf 1.7 gestoßen.
Alarmierend ist, dass mein Kunde in der Java-Systemsteuerung eine Einstellung entdeckt hat, die dieses Problem behebt.
Auf der Registerkarte "Erweitert" können Sie "SSL 2.0-kompatibles ClientHello-Format verwenden" aktivieren.
Dies scheint das Problem zu lösen.
Wir verwenden Java-Applets in einem Internet Explorer-Browser.
Hoffe das hilft.
quelle
Ich hatte das gleiche Problem mit einem Ubuntu Linux-Server, auf dem Subversion ausgeführt wurde, wenn über Eclipse zugegriffen wurde.
Es hat sich gezeigt, dass das Problem mit einer Warnung beim (erneuten) Start von Apache zu tun hat:
Dies ist auf einen neuen Eintrag in zurückzuführen
ports.conf
, bei demNameVirtualHost
neben der Richtlinie in eine weitere Richtlinie eingegeben wurdesites-enabled/000-default
.Nach dem Entfernen der Direktive
ports.conf
war das Problem verschwunden (natürlich nach dem Neustart von Apache).quelle
Nur um hier eine Lösung hinzuzufügen. Dies kann für LAMP-Benutzer hilfreich sein
Die oben erwähnte Zeile in der Konfiguration des virtuellen Hosts war der Schuldige.
Konfiguration des virtuellen Hosts bei Fehler
Arbeitskonfiguration
quelle
Hier ist eine Lösung für Appache httpclient 4.5.11. Ich hatte ein Problem mit dem Zertifikat, das den Platzhalter hat
*.hostname.com
. Es gab mir dieselbe Ausnahme zurück, aber ich sollte das Deaktivieren nach Eigenschaften nicht verwenden,System.setProperty("jsse.enableSNIExtension", "false");
da es im Google-Standortclient einen Fehler gemacht hat.Ich habe eine einfache Lösung gefunden (nur Socket modifizieren):
quelle
Es gibt eine einfachere Möglichkeit , einfach Ihren eigenen HostnamenVerifier zu verwenden, um bestimmten Verbindungen implizit zu vertrauen. Das Problem tritt bei Java 1.7 auf, wo SNI-Erweiterungen hinzugefügt wurden und Ihr Fehler auf eine Fehlkonfiguration des Servers zurückzuführen ist.
Sie können entweder "-Djsse.enableSNIExtension = false" verwenden, um SNI in der gesamten JVM zu deaktivieren, oder meinen Blog lesen, in dem ich erkläre, wie ein benutzerdefinierter Verifizierer über einer URL-Verbindung implementiert wird.
quelle