Wiki-Quellcode von Java-Keystores

Zuletzt geändert von MACH ProForms GmbH am 28.03.2025

Zeige letzte Bearbeiter
1 {{toc/}}
2
3 # Erstellung eines Java-Keystore für Zertifikats Authentifikation
4
5 Ein Java-Keystore kann auch mit Hilfe der Kommando-Zeile auf dem Server erstellt werden.
6 Der Java-Keystore zur Zertifikats Authentifikation muss mehreren Anforderungen gerecht werden:
7
8 * Enthält **MINDESTENS EIN** Server-Zertifikat
9 * Enthält **EINEN** Client-Schlüssel
10 * Enthält **EIN** Client-Zertifikat
11 * Verwendet **EIN** Passwort zur Entschlüsselung
12
13 Wenn bereits ein eigener, vollständig signiertes Schlüsselpaar vorhanden ist, kann ab dem Punkt Konvertieren in PKCS12 weitergemacht werden.
14
15 ## Server-Client-Schlüsselpaar erstellen
16
17 Es muss ein signiertes Schlüsselpaar vorliegen, um die Authentifikation zu erlauben. Am sichersten hierzu ist ein spezielles Schlüsselpaar pro Server, welches an die entsprechenden Clients weitergegeben wird.
18
19 Zuerst muss ein CA-Zertifikat erstellt werden. Dies lässt sich z. B. mit
20
21 ```bash
22 openssl genrsa -des3 -out ca.key 4096
23 openssl req -new -x509 -days 356 -key ca.key -out ca.crt
24 ```
25
26 bewerkstelligen. Wie man deutlich sehen kann, ist das erstellte Zertifikat ein Jahr lang gültig (`-days 356`), danach sollte ein neues erstellt werden, oder die Gültigkeit wird direkt höher gesetzt - ziehen Sie hierzu die OpenSSL-Anleitung zu Rate.
27
28 Danach sollte mit
29
30 ```bash
31 openssl genrsa -des3 -out server.key 4096
32 openssl req -new -key server.key -out server.csr
33 openssl x509 -req -days 356 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 100 -out server.crt
34 ```
35
36 das Server-Zertifikat erstellt und signiert werden und mit
37
38 ```bash
39 openssl genrsa -des3 -out client.key 4096
40 openssl req -new -key client.key -out client.csr
41 openssl x509 -req -days 356 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 101 -out client.crt
42 ```
43
44 das gleiche mit dem Client-Zertifikat getan werden.
45
46 ## Konvertieren in PKCS#12
47
48 Das Client-Schlüsselpaar muss in das _PKCS#12_-Format umgewandelt werden. Dies kann bewerkstelligt werden mit
49
50 ```bash
51 openssl pkcs12 -export -inkey client.key -in client.crt -out client.p12
52 ```
53
54 was das Client-Zertifikat und den entsprechenden Schlüssel in das benötigte Format umwandelt. Hierbei wird ein Passwort erfragt, welches den Client-Schlüssel sichert. Das hier angegebene Password **MUSS ZWINGEND** mit dem Passwort übereinstimmen, welches für den KeyStore verwendet wird.
55
56 ## Zertifikate in KeyStore konvertieren
57
58 Zur einfachen Konvertierung von PKCS12 Zertifikaten in Java-Keystores (JKS) bieten wir Ihnen die Möglichkeit diese Umwandlung mit einem Werkzeug durchzuführen, welches Ihnen auf unserer Seite [Java-Keystore Konverter Tools](https://jks-konverter.machproforms.de/) bereitgestellt wird.
59
60 ### Alternativ:
61
62 #### **KeyStore Explorer**
63
64 * Das Tool KeyStore Explorer lässt sich hier herunterladen: [https://keystore-explorer.org/](https://keystore-explorer.org/)
65 * Zum Ausführen wird eine Java Laufzeitumgebung benötigt (z.B. als Teil eines aktuellen JDK).
66 * Mit diesem Tool können die Inhalte eines keystores betrachtet und gegebenenfalls auch [Konvertierungen](https://keystore-explorer.org/doc/5.5/keyStoreManagement.html#change-a-keystores-type)von PKCS12 nach JKS durchgeführt werden.
67
68 #### **Java-Keytool**
69
70 Die entsprechende _.p12_-Datei kann, nach den oben genannten Schritten, auch mit Hilfe des Java-Keytools in der Kommando-Zeile in einen gültigen JKS umgewandelt werden:
71
72 ```bash
73 keytool -importkeystore -srckeystore client.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore auth.jks
74 ```
75
76 Dieser Befehl wird einen neuen Java-Keystore mit den Namen auth.jks anlegen, in dem die entsprechenden Zertifikate abgelegt sind. Dabei wird ein Passwort vergeben. Dieses **MUSS ZWINGEND** mit dem Passwort übereinstimmen, welches für den Client-Schlüssel angegeben wurde.
77
78 ## Serverzertifikate einfügen
79
80 Damit eine vollständige Zertifizierungskette eingerichtet wird, müssen die entsprechenden Serverzertifikate mit in den Keystore eingefügt werden. Ohne diese ist eine zertifikatsbasierte Authentifikation nicht möglich. Um die vorhandenen X-509-Zertifikate in den Keystore zu importieren, muss folgender Befehl verwendet werden:
81
82 ```bash
83 keytool -keystore auth.jks -importcert -alias <ALIAS> -file <CERT>
84 ```
85
86 Aus dem Beispiel oben wäre in diesem Fall die Datei `server.crt` zu verwenden.
87
88 ## Serverzertifikate abrufen
89
90 Wenn Ihnen die Serverzertifikate nicht vorliegen, Sie diese aber benötigen, können Sie mit Hilfe des `openssl`-Tools die Zertifikate anzeigen lassen und speichern. Davon ausgehend, dass eine direkte Verbindung zum Host möglich ist, kann folgender Befehl verwendet werden:
91
92 ```bash
93 echo -n | openssl s_client -connect <HOST>:<PORT> \
94 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > <TARGET>.crt
95 ```
96
97 Dieser Befehl speichert das Serverzertifikat in der definierten Datei `<TARGET>.crt`. Wenn nicht nur das Server-Zertifikat, sondern die gesamte Zertifizierungskette (Server-Zertifikat, Intermediär, Root) benötigt wird, kann zusätzlich der Parameter `-showcerts` nach `s_client` angegeben werden. Dieser zeigt alle Zertifikate an und diese werden dann innerhalb der `crt`-Datei abgelegt. Es wird empfohlen, die erstellte Datei mit mehreren Zertifikaten zu trennen, und die Zertifikate in separaten Dateien abzulegen, um diese danach zu importieren.
98
99 Sollte das Ziel ein Multi-Domain Host sein, ist es notwendig zusätzlich den Parameter `-servername <HOSTNAME>` anzugeben, um das korrekte Serverzertifikat herunterzuladen.
100
101 # Test der Serverzertifikate
102
103 <ins>Hinweis</ins>: Anleitung gilt für Docker-Umgebungen
104
105 ```bash
106 cd /opt/docker/fs
107 docker exec -it fs_wildfly_1 bash
108 jshell –v
109 ```
110
111 ```bash
112 import javax.net.ssl.SSLSocket;
113 import javax.net.ssl.SSLSocketFactory;
114 import java.io.*;
115
116 /** Establish a SSL connection to a host and port, writes a byte and
117 * prints the response.
118 */
119 public class SSLPoke {
120 public static void main(String[] args) {
121 if (args.length != 2) {
122 System.out.println("Usage: "+SSLPoke.class.getName()+" <host> <port>");
123 System.exit(1);
124 }
125 try {
126 SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
127 SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));
128
129 InputStream in = sslsocket.getInputStream();
130 OutputStream out = sslsocket.getOutputStream();
131
132 // Write a test byte to get a reaction :)
133 out.write(1);
134
135 while (in.available() > 0) {
136 System.out.print(in.read());
137 }
138 System.out.println("Successfully connected");
139
140 } catch (Exception exception) {
141 exception.printStackTrace();
142 }
143 }
144 }
145 ```
146
147 ```bash
148 java.lang.String[] url = { "heise.de" , "443"};
149 SSLPoke.main(url);
150 ```