thommyslaw
Mitglied
Ich möchte einen Datei-Download über eine https-URL realisieren.
Ich möchte über Zertifikate sicherstellen, dass der Host, von dem ich die Datei runterlade, auch der richtige ist.
Also habe ich das Server-Zertifikat mit Hilfe des Firefox runtergeladen und daraus eine lokale keystore erzeugt.
Das Ganze funktioniert auch schon wunderbar wie folgt:
(Verwendet man hier die KeyManagerFactory statt der TrustManagerFactory, führt dies zum gleichen Ergebnis.)
Was nun auffällt, wenn ich die Verbindung mit Hilfe von Wireshark betrachte, dass das Ganze scheinbar auch ohne eine eigene lokale keystore funktioniert, nämlich so:
Ist eine Authentifizierung mit Hilfe des Server-Zertifikats möglich oder benötige ich dazu einen eigenen Key, damit ich auch tatsächlich identifiziert werde?
Ein Download (URL siehe unten) über den Webbrowser ist über https ohne gesonderte Authentifizierung möglich, da VeriSign-Zertifikate ja im Betriebssystem als vertrauenswürdig abgelegt sind, wenn ich das richtig verstehe. Kann es sein, dass sich mein zweites Snippet an dem Betriebssystem-Zertifikat bedient?
Der Ablauf (Handshake, etc.) der Verbindung ist wirklich haargenau der gleiche wie beim 1. Snippet.
Konkret handelt es sich um den Download dieser Datei:
https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml
Ich möchte über Zertifikate sicherstellen, dass der Host, von dem ich die Datei runterlade, auch der richtige ist.
Also habe ich das Server-Zertifikat mit Hilfe des Firefox runtergeladen und daraus eine lokale keystore erzeugt.
Das Ganze funktioniert auch schon wunderbar wie folgt:
Java:
// access local keystore (created with keytool, contains ECB server certificate)
KeyStore keystore = KeyStore.getInstance("JKS");
keystore.load(MyClass.class.getResourceAsStream("client.keystore"), "changeit"
.toCharArray());
// put keystore and trustManager together
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keystore);
// build up SSL context with TLS protocol
SSLContext context = SSLContext.getInstance("TLS");
TrustManager[] trustManagers = tmf.getTrustManagers();
context.init(null, trustManagers, null);
// get a socket from our freshly created factory
SSLSocketFactory sf = context.getSocketFactory();
InetAddress add = InetAddress.getByName(HOST); // HOST = "www.ecb.europa.eu"
Socket socket = sf.createSocket(add, 443);
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.write("GET /stats/eurofxref/eurofxref-hist-90d.xml HTTP/1.0\n\n");
out.flush();
String line;
while ((line = in.readLine()) != null) {
// save to local file
}
out.close();
in.close();
Was nun auffällt, wenn ich die Verbindung mit Hilfe von Wireshark betrachte, dass das Ganze scheinbar auch ohne eine eigene lokale keystore funktioniert, nämlich so:
Java:
URL url = new URL(FILE_URL); // URL mit https://www...
// Open connection and get the content as input stream
HttpURLConnection con = (HttpURLConnection) url.openConnection();
InputStream is = con.getInputStream();
// OutputStream ...
Ist eine Authentifizierung mit Hilfe des Server-Zertifikats möglich oder benötige ich dazu einen eigenen Key, damit ich auch tatsächlich identifiziert werde?
Ein Download (URL siehe unten) über den Webbrowser ist über https ohne gesonderte Authentifizierung möglich, da VeriSign-Zertifikate ja im Betriebssystem als vertrauenswürdig abgelegt sind, wenn ich das richtig verstehe. Kann es sein, dass sich mein zweites Snippet an dem Betriebssystem-Zertifikat bedient?
Der Ablauf (Handshake, etc.) der Verbindung ist wirklich haargenau der gleiche wie beim 1. Snippet.
Konkret handelt es sich um den Download dieser Datei:
https://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist-90d.xml