# url.openStream()  wirft javax.net.ssl.SSLHandshakeException



## washpuda123 (21. Mrz 2019)

Hallo, 

ich habe eine kleine Applikation geschrieben, die Bilder von meiner Webseite laden soll. 
Wenn ich die Applikation auf einem Rechner installiert habe und mit

```
URL url =  new URL("https://www.meineSeite.de/Unterlagen/"Bilder.zip");
url.openStream()
```

die Verbindung starte, wird mir auf einigen (nicht allen) Rechnern die nachfolgende Fehlermeldung ausgegeben. 


```
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
    at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
    at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
    at sun.security.ssl.Handshaker.processLoop(Unknown Source)
    at sun.security.ssl.Handshaker.process_record(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
    at java.net.URL.openStream(Unknown Sour
```

Verwunderlich ist, dass die Funktion bei einigen Rechnern funktioniert und bei anderen nicht. Um das Problem zu lösen, habe ich Eclipse inkl. meinem Quelltext auf einen USB-Stick an einem Rechner ausgeführt wo der Fehler auftritt. Habe ich mein Programm auf dem Stick mit Eclipse ausgeführt gab es keine Probleme, habe ich das auf dem Rechner installierte Programm ausgeführt kam es zu diesen Fehler. 


ich habe dazu schon einiges im Internet recherchiert, habe aber keine Lösung gefunden die mir geholfen hat (scheitert vermutlich auch etwas an meinen Englisch). Es hat etwas mit Zertifikaten zu tun (warum auch immer man diese braucht). 

Ein vielversprechendes Beispiel habe ich unter http://code.naishe.in/2011/07/looks-like-article-no-more-unable-to.html gefunden. Ich weiß aber nicht was ich genau mit der generierten Datei "jssecacerts" machen soll.

ich hoffe mir kann jemand helfen oder einfach erklären wie ich vorgehen muss.


----------



## Dompteur (21. Mrz 2019)

Wenn deine Url mit https (im Gegensatz zu http) beginnt, dann wird der Traffic nicht nur verschlüsselt, sondern es finden auch diverse Prüfungen zur Identität des Servers statt.
Dazu benötigst du Zertifikate (entweder das konkrete deiner Seite oder ein Root-Zertifikat). Diese Zertifikate liegen im Truststore.
Ich nehme einmal an, dass du den Pfad zum Truststore-File bei Aufruf deines Programmes nicht angibst. Dann wird der in der Java-Distribution mitgelieferte verwendet.

Gib einmal auf der Kommandokonsole folgendes ein: dir %JAVA_HOME%\jre\lib\security\cacerts
Dann siehst du, welches Truststore-File deine Java VM verwendet.

Diese Truststores auf den verschiedenen Maschinen dürften sich nun unterscheiden.

Eine Möglichkeit ist nun, dass das Root-Zertifikat mit dem dein Zertifikat signiert ist, erst in einer neueren Java-Version bzw -Build dazugekommen ist und in den älteren fehlt.
Da hilt das Upgrade von Java auf einen aktuelleren Build.

Wenn das nicht geht, dann kannst du deinen Truststore mit deinem Programm ausliefern und bei Aufruf den Pfaf zum File als Systemproperty angeben.
Dazu würdest du bei Aufruf folgendes in der Kommandozeile mitaufnehmen : -Djavax.net.ssl.trustStore=path/to/trustStore.jks


----------



## washpuda54 (4. Apr 2019)

Hallo Dompteur, 

vielen Dank für deine ausführliche Beschreibung. Ich habe mich nochmals intensiv mit dem Sachverhalt auseinander gesetzt, konnte jedoch das Problem immer noch nicht lösen. Hier hatte mich auch ein erfahrener IT-ler unterstützt. 

Ich habe auf einem Rechner, wo das Problem auftritt eine aktuelle Java-Version in das Installationsverzeichnis installiert  (das globale Java habe ich deaktiviert, damit sicher die jre aus den Installationsverzeichnis verwendet wird). Auf einmal hat es funktioniert, wie sich nachträglich aber herausstellte, auf Grund für den Kopiervorgang erforderliche Admin-Rechte, die vom Administrator kurzzeitig freigeschaltet wurden. Ich habe auch eine crt-Datei meiner Hompage in das security-Verzeichnis der JRE eingefügt. Auch das ohne erfolg. 

 Es muss irgendetwas durch fehlende Admin-Rechte blockiert sein. Dei Freischaltung der Firewall für das Programm hat nichts gebracht, es gab auch keine Blockierung durch den Virenscanner.  

Ich hoffe es hat noch jemand eine andere Idee.


----------



## Dompteur (4. Apr 2019)

Ich würde einmal schauen, ob es ein Problem speziell mit deiner Seite gibt oder du generell nicht auf https Urls zugreifen kannst.
Wenn du Seiten findest, wo es funktioniert, dann müsste man sich das Zertifikat deiner Seite ansehen. Dazu müsstest du uns diese aber verraten...


----------



## washpuda123 (2. Mai 2019)

Hallo Dompteur,

sorry das eine Weile vergangen ist, ich habe aber derzeit eine Menge um die Ohren. Ich bin mir sicher, dass es kein Rechteproblem ist, da der Fehler generell beim Herunterladen (z. B. bei irgend ein Bild aus dem Internet) erfolgt. Habe mir dazu extra eine kleine Funktion geschrieben, die eine URL abfragt und versucht diese herunter zu laden. 

Ich bin schon ein Stück weitergekommen, habe das Problem aber noch nicht vollständig gelöst. Wenn der Nutzer als Administrator angemeldet ist, gibt es kein Problem (Das Programm als Administrator zu starten reicht nicht). Wenn ich das JDK von Amazon oder open Java verwende gibt es keine Probleme, hier muss man nicht einmal als Administrator angemeldet sein.

Da ich nicht weiß, welche Java-Version der Anwender verwendet, muss es doch bei allen Funktionieren. Leider gibt es bei Oracle eine Java.security.ProviderException: Coult not derive Key. Die Infos dazu im Internet scheinen im ersten Schritt ausführlich konnten mir jedoch leider auch nicht weiterhelfen. Ich vermute, das bei Oracle lediglich eine Property zu setzen ist, leider weiß ich nicht welche. 

Ich würde mich freuen, wenn hier jemand noch eine Idee hat.

mfg.


----------



## mrBrown (2. Mai 2019)

washpuda123 hat gesagt.:


> Ich bin mir sicher, dass es kein Rechteproblem ist,


Dies hier klingt aber sehr nach Rechteproblem:


washpuda123 hat gesagt.:


> Wenn der Nutzer als Administrator angemeldet ist, gibt es kein Problem



Darf der aktuelle Nutzer irgendeine Datei auf dem JRE nicht lesen?
Wie hast du das (Oracle?) JRE installiert? Du schreibst da irgendwas von kopieren, wofür man Adminrechte bräuchte...


----------



## kneitzel (2. Mai 2019)

Also das ist eine interessante Sache. Ich habe da auch einmal etwas nach gesucht und es kann durchaus daran liegen, dass es Probleme mit einem TLS Handshake gibt.  In einem Thread ist BouncyCastle als Lösung angegeben worden. Da wurden von BouncyCastle die Provider mit eingebunden und dann war der Fehler behoben.

(War also auch diese Situation, wie von Dir beschrieben: Oracle JRE geht nicht, Open JDKs funktionieren mit gleichem Code)

Vielleicht willst Du es einmal ausprobieren? http://www.bouncycastle.org/wiki/display/JA1/Provider+Installation  beschreibt auch eine statische Installation beim jre, d.h. ohne Anpassung des Codes. Ein Versuch kann es ja mal wert sein.


----------



## washpuda123 (8. Mai 2019)

Hallo mrBrown, 

Ich vermute auch, dass beim Java von Oracle irgend ein schreibender Dateizugriff erfolgt, der aus Adminrechten nicht erfolgen kann, der beim Open Java nicht erforderlich ist. Nachfolgend einmal die ganze Fehlermeldung. 


```
javax.net.ssl.SSLException: java.security.ProviderException: Could not derive key
            at java.base/sun.security.ssl.Alerts.getSSLException(Unknown Source)
            at java.base/sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
            at java.base/sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
            at java.base/sun.security.ssl.SSLSocketImpl.handleException(Unknown Source)
            at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
            at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
            at java.base/sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
            at java.base/sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
            at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source)
            at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
            at java.base/sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
            at java.base/java.net.URL.openStream(Unknown Source)
            at picturemap.Prog$3.run(Prog.java:764)
```

Java selbst habe ich einmal direkt über den Java-Installer installiert (Programme sind gestartet) oder ins Installationsverzeichnis meines Java-Programmes installiert (auch sichergestellt, das mein Programm dieses Java verwendet). Der Fehler tritt bei beiden varianten auf, insofern ich das Java von Oracle verwende.

Mit dem Link von kneitzel konnte ich leider nichts anfangen. Ich möchte in jedem Fall vermeiden eine zusätzliche API zu verwenden.


----------



## kneitzel (8. Mai 2019)

Kannst Du dann bitte einmal vom openjdk und vom Oracle JDK jeweils die java.security files vergleichen oder zeigen?

Speziell die Keys
- jdk.certpath.disabledAlgorithms
- jdk.tls.disabledAlgorithms
würden mich einmal interessieren.

Dann könntest Du auch einmal die Details des SSL Zertifikates von der Seite, auf die du zugreifst, nennen.

Evtl. können wir da der Ursache etwas näher kommen und weitere Lösungsideen vorstellen.

Und nein: Aus meiner Sicht wird nicht an Dateizugriffen liegen. Aber Du kannst da gerne mit einem Prozessmonitor prüfen, ob es beim Zugriff auf die URL irgendwelche Fehlgeschlagenen Dateioperationen gab...


----------

