Java-Keystores

Zuletzt geändert von MACH ProForms GmbH am 28.03.2025

Erstellung eines Java-Keystore für Zertifikats Authentifikation

Ein Java-Keystore kann auch mit Hilfe der Kommando-Zeile auf dem Server erstellt werden.
Der Java-Keystore zur Zertifikats Authentifikation muss mehreren Anforderungen gerecht werden:

  • Enthält MINDESTENS EIN Server-Zertifikat
  • Enthält EINEN Client-Schlüssel
  • Enthält EIN Client-Zertifikat
  • Verwendet EIN Passwort zur Entschlüsselung

Wenn bereits ein eigener, vollständig signiertes Schlüsselpaar vorhanden ist, kann ab dem Punkt Konvertieren in PKCS12 weitergemacht werden.

Server-Client-Schlüsselpaar erstellen

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.

Zuerst muss ein CA-Zertifikat erstellt werden. Dies lässt sich z. B. mit

openssl genrsa -des3 -out ca.key 4096
openssl req -new -x509 -days 356 -key ca.key -out ca.crt

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.

Danach sollte mit

openssl genrsa -des3 -out server.key 4096
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 356 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 100 -out server.crt

das Server-Zertifikat erstellt und signiert werden und mit

openssl genrsa -des3 -out client.key 4096
openssl req -new -key client.key -out client.csr
openssl x509 -req -days 356 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 101 -out client.crt

das gleiche mit dem Client-Zertifikat getan werden.

Konvertieren in PKCS#12

Das Client-Schlüsselpaar muss in das PKCS#12-Format umgewandelt werden. Dies kann bewerkstelligt werden mit

openssl pkcs12 -export -inkey client.key -in client.crt -out client.p12

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.

Zertifikate in KeyStore konvertieren

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 bereitgestellt wird.

Alternativ:

KeyStore Explorer

  • Das Tool KeyStore Explorer lässt sich hier herunterladen: https://keystore-explorer.org/
    • Zum Ausführen wird eine Java Laufzeitumgebung benötigt (z.B. als Teil eines aktuellen JDK).
  • Mit diesem Tool können die Inhalte eines keystores betrachtet und gegebenenfalls auch Konvertierungenvon PKCS12 nach JKS durchgeführt werden.

Java-Keytool

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:

keytool -importkeystore -srckeystore client.p12 -srcstoretype PKCS12 -deststoretype JKS -destkeystore auth.jks

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.

Serverzertifikate einfügen

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:

keytool -keystore auth.jks -importcert -alias <ALIAS> -file <CERT>

Aus dem Beispiel oben wäre in diesem Fall die Datei server.crt zu verwenden.

Serverzertifikate abrufen

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:

echo -n | openssl s_client -connect <HOST>:<PORT> \
| sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > <TARGET>.crt

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.

Sollte das Ziel ein Multi-Domain Host sein, ist es notwendig zusätzlich den Parameter -servername <HOSTNAME> anzugeben, um das korrekte Serverzertifikat herunterzuladen.

Test der Serverzertifikate

Hinweis: Anleitung gilt für Docker-Umgebungen

cd /opt/docker/fs
docker exec -it fs_wildfly_1 bash
jshell –v
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;

/** Establish a SSL connection to a host and port, writes a byte and
 * prints the response.
 */
public class SSLPoke {
    public static void main(String[] args) {
 if (args.length != 2) {
   System.out.println("Usage: "+SSLPoke.class.getName()+" <host> <port>");
   System.exit(1);
 }
  try {
   SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
   SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(args[0], Integer.parseInt(args[1]));

   InputStream in = sslsocket.getInputStream();
   OutputStream out = sslsocket.getOutputStream();

   // Write a test byte to get a reaction :)
   out.write(1);

  while (in.available() > 0) {
    System.out.print(in.read());
  }
   System.out.println("Successfully connected");

 } catch (Exception exception) {
   exception.printStackTrace();
 }
}
}
java.lang.String[] url = { "heise.de" , "443"};
SSLPoke.main(url);