Wiki-Quellcode von Java-Keystores
Zuletzt geändert von MACH formsolutions 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 | ``` |