
Ein Kroxylicious-Filter-Plugin, das transparente Post-Quanten-Verschlüsselung (ML-KEM + AES-256-GCM) auf Datensatzebene für Apache Kafka bereitstellt – ohne dass Änderungen am Client-Code erforderlich sind.
Ein Kroxylicious-Filter-Plugin, das transparente Post-Quanten-Kryptografie (PQC)-Verschlüsselung auf Datensatzebene für Apache Kafka mithilfe von ML-KEM (FIPS 203)-Schlüsselkapselung mit AES-256-GCM-symmetrischer Verschlüsselung bietet.
Kafka-Producer und -Consumer benötigen keinerlei Codeänderungen. Der Kroxylicious-Proxy fängt den Datenverkehr ab und verschlüsselt bei Produce / entschlüsselt bei Fetch automatisch.``` Producer ──plaintext──> Kroxylicious ──encrypted──> Kafka Broker Consumer <──plaintext── Kroxylicious <──encrypted── Kafka Broker
## Warum PQC für Kafka?
Klassische Schlüsselvereinbarungsalgorithmen (RSA, ECDH) sind anfällig für zukünftige
Quantencomputer. Wenn Verschlüsselungsschlüssel pro Datensatz mithilfe eines
klassischen KEM etabliert werden, könnte ein Quantengegner diese Schlüssel aus den
Verkapselungen wiederherstellen, die neben dem Chiffrat auf dem Broker gespeichert sind.
Dieses Plugin verwendet ML-KEM (FIPS 203) zur quantenresistenten Schlüsselverkapselung,
sodass Daten im Ruhezustand auf dem Kafka-Broker selbst von einem
Gegner mit einem kryptografisch relevanten Quantencomputer nicht entschlüsselt werden können.
**Hinweis:** Dieser Filter schützt **Daten im Ruhezustand auf dem Broker**, nicht den TLS-
Kanal während der Übertragung. Siehe [THREAT_MODEL.md](https://github.com/oscerd/kroxylicious-pqc-filter/blob/main/THREAT_MODEL.md) für eine vollständige
Analyse dessen, was verteidigt wird und was nicht.
| Standard | Algorithmus | Zweck in diesem Plugin |
|----------|-----------|------------------------|
| FIPS 203 | ML-KEM (Kyber) | Schlüsselverkapselung - etabliert sicher einen AES-Schlüssel pro Nachricht |
| N/A | AES-256-GCM | Symmetrische authentifizierte Verschlüsselung der Datensatz-Nutzlast |
| N/A | X25519 ECDH | Klassische Schlüsselvereinbarung für den Hybrid-Modus mit Verteidigung in der Tiefe |
## Funktionen
- **Transparente Ver-/Entschlüsselung** - keine clientseitigen Änderungen erforderlich
- **Parametersätze ML-KEM-512, ML-KEM-768 (Standard), ML-KEM-1024**
- **Hybrid-Modus** (Standard) - kombiniert ML-KEM + X25519 ECDH, sodass beide gebrochen werden müssen
- **Verschlüsselung pro Datensatz** - jeder Datensatz erhält eine frische KEM-Verkapselung + zufälligen IV
- **Topic-Filterung** - Regex-Muster wählen aus, welche Topics verschlüsselt werden
- **Manipulationserkennung** - die authentifizierte AES-GCM-Verschlüsselung weist verändertes Chiffrat zurück
- **Semantische Sicherheit** - identische Klartexte erzeugen unterschiedliche Chiffrate (IND-CCA2)
- **Automatische Schlüsselerzeugung** - erzeugt und speichert ML-KEM-Schlüssel beim ersten Start, falls nicht vorhanden
- **`x-pqc-encrypted`-Header** - kennzeichnet verschlüsselte Datensätze für nachgelagerte Komponenten
- **Plugbare Schlüsselanbieter** - das `KeyProvider`-SPI unterstützt Dateisystem- (Standard) und HashiCorp-Vault-Backends
## Voraussetzungen
| Anforderung | Version |
|-------------|---------|
| JDK | 17+ (21+ empfohlen) |
| Maven | 3.8+ |
| Kroxylicious | 0.19.0 |
| Apache Kafka | 3.9.x |
## Schnellstart
### 1. Plugin bauen```bash
git clone <this-repo>
cd kroxylicious-pqc-filter
mvn clean package -DskipTests
Das Shaded-JAR unter target/kroxylicious-pqc-filter-1.0.0-SNAPSHOT.jar bündelt
Bouncy Castle, sodass es ohne zusätzliche Abhängigkeiten in Kroxylicious eingesetzt werden kann.
Um die Unterstützung für den HashiCorp-Vault-Schlüsselanbieter einzubinden, bauen Sie mit dem vault-Profil:```bash
mvn clean package -Pvault -DskipTests
Dies bündelt `spring-vault-core` und den `VaultKeyProvider` in das JAR.
### 2. ML-KEM-Schlüssel generieren```bash
java -cp target/kroxylicious-pqc-filter-1.0.0-SNAPSHOT.jar \
io.kroxylicious.filter.pqc.PqcKeyGeneratorCli \
ML_KEM_768 \
/etc/kroxylicious/pqc/
I didn't receive any content to translate. The chunk appears to be empty. Please provide the text you'd like translated, and I'll be happy to help.``` Generating ML-KEM-768 key pair... Public key: /etc/kroxylicious/pqc/pqc-public.der Size: 1206 bytes Format: X.509 Private key: /etc/kroxylicious/pqc/pqc-private.der Size: 2498 bytes Format: PKCS#8
Alternativ können Sie die Schlüsselpfade in der Konfiguration weglassen, und der Filter generiert die Schlüssel beim ersten Start automatisch.
### 3. Kroxylicious konfigurieren
Fügen Sie den Filter zu Ihrer Kroxylicious-Proxy-YAML-Konfiguration hinzu:```yaml
filterDefinitions:
- name: pqc-encryption
type: PqcRecordEncryptionFilterFactory
config:
kemAlgorithm: ML_KEM_768
hybridMode: true
publicKeyPath: /etc/kroxylicious/pqc/pqc-public.der
privateKeyPath: /etc/kroxylicious/pqc/pqc-private.der
topicPatterns:
- "sensitive-.*"
- "pii-.*"
defaultFilters:
- pqc-encryption
Legen Sie die JAR-Datei in einem Verzeichnis ab, das für Kroxylicious zugänglich ist, und fügen Sie sie
über die Umgebungsvariable KROXYLICIOUS_CLASSPATH zum Klassenpfad hinzu:```bash
export KROXYLICIOUS_CLASSPATH="/opt/kroxylicious/plugins/*"
Wenn Sie Docker verwenden, setzen Sie es in Ihrer Container-Umgebung:```yaml
environment:
KROXYLICIOUS_CLASSPATH: /opt/kroxylicious/plugins/*
Starten Sie dann den Proxy. Producer und Consumer verbinden sich mit dem Proxy-Port statt direkt mit dem Broker.
| Eigenschaft | Typ | Erforderlich | Standard | Beschreibung |
|---|---|---|---|---|
kemAlgorithm | enum | Nein | ML_KEM_768 | ML-KEM-Parametersatz. Einer von ML_KEM_512, ML_KEM_768, ML_KEM_1024. |
hybridMode | boolean | Nein | true | Kombiniert ML-KEM mit X25519 ECDH für Defense-in-Depth. |
publicKeyPath | string | Nur Dateisystem | - | Dateisystempfad zum ML-KEM-öffentlichen Schlüssel (X.509-DER-codiert). |
privateKeyPath | string | Nur Dateisystem | - | Dateisystempfad zum ML-KEM-privaten Schlüssel (PKCS#8-DER-codiert). |
topicPatterns | list<string> | Nein | [".*"] | Java-Regex-Muster. Nur Records in passenden Topics werden verschlüsselt/entschlüsselt. |
keyProviderType | string | Nein | filesystem | Schlüsselspeicher-Backend. Eines von filesystem, vault. |
keyProviderConfig | map<string, string> | Nur Vault | {} | Backend-spezifische Konfiguration (siehe Vault-Abschnitt unten). |
Filesystem (keyProviderType: filesystem, Standard):
Lädt ML-KEM-Schlüssel aus DER-Dateien von der Festplatte. Falls die Dateien nicht existieren, erzeugt es
ein neues Schlüsselpaar und speichert diese. Erfordert publicKeyPath und privateKeyPath.
HashiCorp Vault (keyProviderType: vault, erfordert -Pvault-Build):
Ruft ML-KEM-Schlüssel aus einer Vault-KV-v2-Secrets-Engine ab. Schlüssel werden als
base64-codiertes DER in den Feldern publicKey und privateKey gespeichert. Vault-Secret-Versionen
werden für die Schlüsselrotation auf Schlüssel-IDs abgebildet.
Vault-keyProviderConfig-Eigenschaften:
| Eigenschaft | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
vaultAddress | Ja | VAULT_ADDR-Umgebungsvariable | Vault-Server-URL (z. B. http://vault:8200) |
vaultToken | Für token-Auth | VAULT_TOKEN-Umgebungsvariable | Vault-Authentifizierungstoken |
secretPath | Ja | -- | Pfad innerhalb der Secrets-Engine (z. B. kroxylicious/pqc) |
secretEngine | Nein | secret | Mount-Name der KV-v2-Secrets-Engine |
authMethod | Nein | token | Authentifizierungsmethode: token, approle oder kubernetes |
roleId | Für approle | -- | AppRole-Rollen-ID |
secretId | Für approle | -- | AppRole-Secret-ID |
kubeRole | Für kubernetes | -- | Name der Kubernetes-Authentifizierungsrolle |
kubeTokenPath | Nein | /var/run/secrets/.../token | Dateipfad zum Serviceaccount-Token |