SSL-Verbindung mit Client-Zertifikat (Private Key) scheitert

Status
Nicht offen für weitere Antworten.

musiKk

Top Contributor
Guten Tag,

ich habe hier einen Server, der nur sichere Verbindungen mit Client-Zertifikat zulässt. Dieses ist zudem selbst signiert. Mein Vorgehen bislang ist wie folgt (Java 6):

Ich habe ein PEM-File mit dem Private Key. Daraus habe ich einen Java-Keystore im JKS-Format erstellt:
Code:
keytool -import -keystore keystore.jks -file mein_keyfile.pem
Mit -list kann ich mir den Eintrag auch toll anzeigen lassen, also scheint zumindest die Erstellung schonmal zu funktionieren.

Dann bin ich auf diese Seite, habe das dort vorhandene Programm InstallCert angepasst und einen Truststore erzeugt (den habe ich, wie das wohl meist geschieht, cacerts genannt).

So. Nun also das ganze mal ausprobieren. Erstmal schaue ich mit einem SSLSocket, ob der Truststore funktioniert:
Java:
System.setProperty("javax.net.ssl.trustStore", "pfad/zum/cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "mein_password");

SSLContext ctxt = SSLContext.getDefault();

SSLSocketFactory ssf = ctxt.getSocketFactory();
SSLSocket socket = (SSLSocket) ssf.createSocket("rechnername", 443);
socket.startHandshake();
socket.close();
Das funktioniert (mit einem HandshakeCompletedListener sieht man das auch, wollte den Code nur kurz halten). Dass mein Truststore funktioniert sehe ich auch daran, dass wenn die Properties nicht gesetzt sind, entsprechende Exceptions fliegen (wie in oben verlinktem Blogeintrag).

Jetzt versuche ich aber z. B. auf den Webserver zuzugreifen, zu welchem ich ja nur per Client-Zertifikat komme. Das klappt nicht:
Java:
System.setProperty("javax.net.ssl.keyStore", "pfad/zum/keystore.jks");
System.setProperty("javax.net.ssl.keyStorePassword", "mein_password");

System.setProperty("javax.net.ssl.trustStore", "pfad/zum/cacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "mein_password");

url = new URL("https://hostname/pfad/zu/einer/existierenden/datei");
URLConnection urlc = url.openConnection();

InputStream is = urlc.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));

String line = null;
while ((line = br.readLine()) != null) {
	System.out.println(line);
}
Dabei erhalte ich diese schöne Exception (erscheint in Zeile 10 in obigem Listing):
Code:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1657)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:932)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:746)
	at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75)
	at java.io.BufferedInputStream.fill(BufferedInputStream.java:218)
	at java.io.BufferedInputStream.read1(BufferedInputStream.java:258)
	at java.io.BufferedInputStream.read(BufferedInputStream.java:317)
	at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:687)
	at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632)
	at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:652)
	at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1000)
	at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:234)
	at client.Cert.main(Cert.java:47)
Dabei ist es irrelevant, ob ich das Client-Zertifikat einfüge, oder nicht. Die Passwörter der Keystores stimmen; jedenfalls funktionieren sie bei einem "keytool -list". Der Pfad zu der Datei stimmt auch, weil per Firefox und importiertem Zertifikat (dort hat es natürlich nicht das proprietäre JKS-Format, sondern PKCS#11) klappt es.

Irgendetwas habe ich wohl noch falsch. Meine Frage natürlich nun: Was könnte das sein? Ich habe irgendwie das Gefühl, dass der private Schlüssel aus dem .pem-File nicht in den Keystore übertragen wird, aber ich kann mir nach viel Googelei nicht so recht erklären, wie es anders gemacht werden könnte.
 

musiKk

Top Contributor
Naja, was auch immer; ich habs jetzt. Es lag wirklich gleich am Anfang, das keytool funktioniert doch etwas anders, als ich dachte (um nicht zu sagen unintuitiv).
 

scaary

Bekanntes Mitglied
Hi.
Wie hasten das geloest?
Ich hab nen aehnliches Probelm mit nem Zugriff auf ne Seite, hab das ganze auch mit Keytool eingebunden laut folgender Anleitung:

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

Aber trotzdem krieg ich noch ne fehlermeldung.

Als testseite (um zu gucken, damit ich das hinbekomme), hab ich einfach mal die Seite des Arbeitsamts genommen:

Java:
import java.io.*;
import java.net.*;

public class Loader{

    static URL kJobs;

    static InputStream is = null; 
    static DataInputStream dis;
    static String s;

    public static void main(String[] args) {
	try {
	    kJobs = new URL("https://jobboerse2.arbeitsagentur.de/vam/vamController/SchnellsucheAG/anzeigeSchnellsuche?rqc=11950951693&rqv=-474859825961505844");
	    is = kJobs.openStream();
	    dis = new DataInputStream(new BufferedInputStream(is));

	    while ((s = dis.readLine()) != null) {
		System.out.println(s);
	    }
	    
	} catch (MalformedURLException mue) {

	    System.out.println("Ouch - a MalformedURLException happened.");
	    mue.printStackTrace();
	    System.exit(1);

	} catch (IOException ioe) {

	    System.out.println("Oops- an IOException happened.");
	    ioe.printStackTrace();
	    System.exit(1);
	} finally {
	    try {
		is.close();
	    } catch (IOException ioe) {
		// just going to ignore this one
	    }
	}
    }
}

Dabei liest er die Seite erstmal einfach nur ein und gibt sie wieder aus ^^

Kannst du mir sagen, woran das liegt?
Danke!


Edit:

Ahja, fehlermeldung schaut wie folgt:

Java:
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
Oops- an IOException happened.
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
	at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(Unknown Source)
	at sun.net.[url]www.protocol.https.HttpsClient.afterConnect(Unknown[/url] Source)
	at sun.net.[url]www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown[/url] Source)
	at sun.net.[url]www.protocol.http.HttpURLConnection.getInputStream(Unknown[/url] Source)
	at sun.net.[url]www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown[/url] Source)
	at java.net.URL.openStream(Unknown Source)
	at Loader.main(Loader.java:16)
Caused by: 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.validator.PKIXValidator.doBuild(Unknown Source)
	at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
	at sun.security.validator.Validator.validate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
	at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
	... 14 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
	at java.security.cert.CertPathBuilder.build(Unknown Source)
	... 20 more
 

scaary

Bekanntes Mitglied
HI.Ah, danke.

Aber irgendwie peil ich nicht so ganz wie ich das Programm in Eclipse aufrufen kann.

Geht das nur unter Linux?

Oder geht das nur per shell?

Danke!
 

musiKk

Top Contributor
Das ist reines Java mit all seiner plattformunabhängigkeit, darum sollte es eigentlich gehn.

Du kannst es auch anders machen. Geh mit Deinem Browser auf die Seite und schau dort in den Sicherheitsinformationen nach der CA. Dann suchst Du in den Zertifikaten des Browsers nach dem Zertifikat der CA und exportierst die dort. Bei mir im Opera heißt die für Deine Beispielseite "TC Trust Center, Germany, Class 3 CA" (ich weiß nicht, ob der Name variabel sein kann). Dieses exportierte Zertifikat (am besten im PEM-Format) kannst du mit dem keytool einem Truststore (cacerts) hinzufügen (oder einen neuen erstellen):
Code:
keytool -importcert -file das_exportierte_zertifikat.pem -keystore cacerts -storepass password
Das keytool liegt in <jdk-pfad>/bin/keytool.
 

scaary

Bekanntes Mitglied
Deshalb hat es mich gewundert ^^

Ich mach warscheinlihch noch was falsch.

Wenn ich das Proggie aufrufe, kommt folgende Ausgabe

Java:
Usage: java InstallCert <host>[:port] [passphrase]

Das wars, Programm zu ende.


Das mit dem Keytool hab ich uebrigens schon gemacht.

Ich bin auf die Seite, hab geschaut welches SSL Protokoll verwendet wird, hab das exportiert, und danach mit dem Keytool eingebunden. es geht immernoch nicht, und ich hab einfach keinen dunst warum :(

Wie gesagt, ich hab ja die Anleitung, nach der ich das gemacht hab, in meinem ersten post verlinkt, und laut ausgabe des Keytools wurde das zertifikat auch erfolgreich eingefuegtl, aber trozdem weigert sich mein Programm eine Verbindung her zu stellen... .

Muss ich host, port und passphrase erst noch initialisieren?

(wenn ja, was genau mach ich da rein? Woher soll ich denn den port wissen?).

Danke !
 
Zuletzt bearbeitet:

musiKk

Top Contributor
Keine Ahnung. In dem Tutorial wird ja der globale truststore des JRE bearbeitet. Davon habe ich bisher immer abgesehen. Ich habe lieber meinen eigenen truststore erstellt und den dann im Programm wie oben eingebunden.

Usage weist darauf hin, mit welchen Parametern Du das Programm aufzurufen hast. Das ist aber keine rocket science. Du kannst ja auch den Quelltext entsprechend ändern. Host ist die Arbeitsagentur, der Port kann wegbleiben, weils der Standardport ist (443) und die passphrase ist für den truststore.
 

scaary

Bekanntes Mitglied
Mhh, ok, bei mir scheiterts grade noch ein wenig am Verstaendnis, fuerchte ich.

Also, das Programm, dass du verlinkt hast, importiert das protokoll in den globalen Truststore?

Oder was genau macht das (wenns denn mal laeuft ^^).

Ich hab anschienend auch noch nicht verstanden, wie ich das Programm aufrufe.

Ich habs derzeit einfach in Eclipse mit ner eigenen Klasse und ruf es da auf, und kriege dann die Usage fehlermeldung.

Das funktioniert aber offensichtlich nicht, da ich args keine Parameter uebergebe, und args daher 0 ist.

Wie also rufe ich das Programm mit den entsprechenden parametern auf?

(sorry dass ich dich jetzt mit Basics langweile, aber das wurde in der Uni bisher noch nicht angesprochen).

Danke!
 

musiKk

Top Contributor
Also, das Programm, dass du verlinkt hast, importiert das protokoll in den globalen Truststore?
http://blogs.sun.com/andreas/entry/no_more_unable_to_find hat gesagt.:
[...]and then added it to a Java KeyStore 'jssecacerts' in the current directory.

Das funktioniert aber offensichtlich nicht, da ich args keine Parameter uebergebe, und args daher 0 ist.

Wie also rufe ich das Programm mit den entsprechenden parametern auf?
Entweder in der Run Configuration bei Program Arguments ${string_prompt} angeben oder die Variablen im Quelltext einfach selbst belegen (was auch nicht schwer gewesen wäre, die nötigen Variablen haben sinnvolle Bezeichnungen).
 

malzbier

Neues Mitglied
Hi Musikk,

ich habe das gleiche Problem wie du. Wenn ich client.pem mit keytool in keystore importieren, geht das privat key irgendwie verloren.
Kannste mir sagen, wie du das löst?Danke!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
X Kann ich einen Client/Server verbindung hinkriegen die mir alle paar Sekunden die aktuellen Daten per Realtime zuschickt ? Netzwerkprogrammierung 9
M Socket Verbindung Matlab(Server) Java(Client) Netzwerkprogrammierung 1
U Client Soap Verbindung wieder schließen Netzwerkprogrammierung 0
F TCP Client, verbindung aufrecht halten Netzwerkprogrammierung 0
P server - client verbindung (anfänger) Netzwerkprogrammierung 8
D TCP Verbindung (Java Client und Visual Basic Server) Netzwerkprogrammierung 12
S Socket Applet Client bekommt keine GLOBALE Verbindung zum Server Netzwerkprogrammierung 25
D Server Client Verbindung - Unexpected End of File - Invalid HTTP Response Netzwerkprogrammierung 4
T Socket Client versucht zyklische Verbindung zum Server Netzwerkprogrammierung 4
P Socket neuer Client - neue(r) Socket/Verbindung geöffnet? Netzwerkprogrammierung 6
Y server client socket verbindung übers internet aufbauen Netzwerkprogrammierung 8
H Socket Client server,verbindung läst sich nicht abbauen&code optimierung Netzwerkprogrammierung 3
H Server und Client-keine verbindung über den localhost Netzwerkprogrammierung 6
B Verbindung zwischen Client und Server Netzwerkprogrammierung 2
F Java Client-Server-Client Verbindung Netzwerkprogrammierung 9
W Socket Client-Server Verbindung. Wie Strings senden? Netzwerkprogrammierung 6
T Server Client Verbindung halten ,wie? Netzwerkprogrammierung 3
R Server/Client Verbindung - Datei schreiben Netzwerkprogrammierung 15
F Verbindung zu einem LDAP Server über Java Netzwerkprogrammierung 4
D Verbindung zu Geräten mit gleicher IP aber in unterschiedlichen VLans aufbauen Netzwerkprogrammierung 2
M Socket Socket lehnt Verbindung ab Netzwerkprogrammierung 3
IAmFloppy Socket Nachstellen der Verbindung Netzwerkprogrammierung 6
M Socket peer to peer Verbindung zwischen Java und Matlab Netzwerkprogrammierung 0
S Bluetooth Verbindung zwischen Android app und Raspberry Pi 3 Netzwerkprogrammierung 1
S Peer2Peer Verbindung trotz NAT Netzwerkprogrammierung 2
T VPN-Verbindung über Java Netzwerkprogrammierung 4
Aruetiise Socket Verbindung Überprüfen Netzwerkprogrammierung 18
F Socket Verbindung mit Verschlüsselung und Authentifierzung Netzwerkprogrammierung 1
F Probleme mit Connection Reset bei Telnet Verbindung Netzwerkprogrammierung 1
M Verbindung zwischen zwei Pc in dem Selben Netzwerk Netzwerkprogrammierung 8
P Socket Socket-Verbindung Input sehr langsam Netzwerkprogrammierung 1
S FTP Verbindung zu einem BS2000 Großrechner mit Commons Net Netzwerkprogrammierung 0
F Einfache Socket Verbindung Netzwerkprogrammierung 2
F Verbindung zwischen Server und handy Netzwerkprogrammierung 1
M TCP Verbindung Byte-weise lesen? Netzwerkprogrammierung 5
Shams Problem mit Eventbus in Verbindung mit Server Netzwerkprogrammierung 0
Z Verbindung zwischen 2 Rechnern über ServerSockets nicht möglich Netzwerkprogrammierung 3
I Swing hängt sich auf bei Verbindung zum Server Netzwerkprogrammierung 3
P RMI Hohe CPU Last RMI Verbindung Netzwerkprogrammierung 4
J Pc - Handy Verbindung? Netzwerkprogrammierung 3
M Socket 2x Proxy multithread-server mit Cross Verbindung Netzwerkprogrammierung 0
T Verbindung zum Server fehlgeschlagen Netzwerkprogrammierung 7
D Einfache Verbindung zu Linux Server und Datei auslesen Netzwerkprogrammierung 13
B Nach Verbindung gleich ObjectStream empfangen Netzwerkprogrammierung 1
R Dauerhaft offene Socket-Verbindung? Netzwerkprogrammierung 3
G Socket Socket verbindung für Chat System Netzwerkprogrammierung 3
S Socket Socket Verbindung wiederherstellen Netzwerkprogrammierung 16
T Socket Bidirektionale Verbindung mit Sockets Netzwerkprogrammierung 8
N (TCP) Verbindung ohne Portforwarding Netzwerkprogrammierung 12
N Lan-Verbindung erstellen Netzwerkprogrammierung 2
H Socket Java Chat - Verbindung zum Server fehlgeschlagen. Netzwerkprogrammierung 5
A TCP über UDP Verbindung? Netzwerkprogrammierung 10
E Verbindung zu SQL-Datenbank auf einem Server Netzwerkprogrammierung 13
V NullPointerException bei Verbindung zu RabbitMQ-Server Netzwerkprogrammierung 4
B FTP commons net verschlüsselte verbindung Netzwerkprogrammierung 11
C Verbindung zu einem Hostrechner über das Internet herstellen Netzwerkprogrammierung 15
X Über eine Socket-Verbindung Arrays übergeben Netzwerkprogrammierung 5
P Socket Verbindung über das Internet Netzwerkprogrammierung 2
A Socket Socket Verbindung unterbrochen --> keine Exception Netzwerkprogrammierung 7
S SVNKit - Verbindung zum Repository trennen? Netzwerkprogrammierung 2
M Problem mit Socket-Verbindung Netzwerkprogrammierung 2
X SSH Verbindung zu Remote Datenbank Netzwerkprogrammierung 2
S TCP Verbindung zu Beamer Netzwerkprogrammierung 8
M ganymed-ssh2.har: ftp-Verbindung über ftp-Proxy Netzwerkprogrammierung 2
D Verbindung zw. zwei Rechnern funzt nicht Netzwerkprogrammierung 5
F Socket Socket Verbindung Netzwerkprogrammierung 10
E Server schließt einfach verbindung? Netzwerkprogrammierung 6
Shoox VPN-Verbindung für Datenbankzugriff Netzwerkprogrammierung 2
X Socket Handy/PC Verbindung unterscheiden Netzwerkprogrammierung 18
O Telnet verbindung Netzwerkprogrammierung 4
Dit_ UDP Verbindung durch Proxy Netzwerkprogrammierung 4
V Verbindung zweier Rechner über das Internet mit Sockets Netzwerkprogrammierung 8
M HTTP HTTPS-Verbindung mittels Java und Javascript Netzwerkprogrammierung 2
N Verbindung zu Fritzbox Socket/Telnet ??? Netzwerkprogrammierung 5
multiholle RMI Verbindung Linux <-> Windows Netzwerkprogrammierung 4
S netzwerkprotokoll auf basis einer tcp verbindung erstellen Netzwerkprogrammierung 9
S SSH Verbindung mit j2ssh Netzwerkprogrammierung 3
H Socket Mit Applet Verbindung zu eigener Website aufbauen Netzwerkprogrammierung 4
H Socket Socket verbindung mit einem TeamSpeak2 Server Netzwerkprogrammierung 5
H TCP verbindung hinter NAT Netzwerkprogrammierung 28
G TCP SSL Verbindung Netzwerkprogrammierung 3
P Java / My-Sql Verbindung herstellen Netzwerkprogrammierung 6
W Socket Shellscript über ssh Verbindung aufrufen Netzwerkprogrammierung 14
N Socket Verbindung wird immer verweigert Netzwerkprogrammierung 5
Dit_ UDP-Verbindung, DatagramPakete Netzwerkprogrammierung 3
S Socket verbindung trennen Netzwerkprogrammierung 3
D Verbindung zu einem Server - POST Netzwerkprogrammierung 2
D Socketprogrammierung Verbindung C++=>Java Netzwerkprogrammierung 23
B Probleme mit FTP verbindung Netzwerkprogrammierung 22
T Mac Adresse über Socket Verbindung abfragen? Netzwerkprogrammierung 9
L SSL Verbindung aber Server wird erst im Programm festgelegt Netzwerkprogrammierung 4
L Https Verbindung wird aus jar heraus nicht aufgebaut Netzwerkprogrammierung 12
M Verbindung über Proxy// Problem mit Outputstream bei URLConn Netzwerkprogrammierung 5
O TCP Socket-Verbindung überprüfen Netzwerkprogrammierung 4
F Peer to Peer Verbindung zwischen mehreren Clients? Netzwerkprogrammierung 8
F applet verbindung zum server Netzwerkprogrammierung 6
T Verbindung über das Internet Netzwerkprogrammierung 2
G Verbindung zwischen PC und Handy Netzwerkprogrammierung 10
B Bibliothek, um Eckdaten zur Internet-Verbindung rauszufinden Netzwerkprogrammierung 2
C Verbindung zwischen 2 Computern herstellen Netzwerkprogrammierung 12

Ähnliche Java Themen

Neue Themen


Oben