Wiki-Quellcode von Java-Keystores
Zuletzt geändert von MACH ProForms GmbH am 28.03.2025
Zeige letzte Bearbeiter
author | version | line-number | content |
---|---|---|---|
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 | ``` |