Den Windows-Dienst ansprechen
Diese Anleitung zeigt, wie ein Programm über die Named Pipe Schlüssel erzeugt, signiert, prüft, verschlüsselt und einen ML-KEM-Schlüsselaustausch ausführt. Die Beispiele sind PowerShell; jede Sprache, die eine Named Pipe öffnen und JSON schreiben kann, funktioniert gleich.
Voraussetzung: Der Dienst läuft, wie unter Bauen und testen
beschrieben, auf \\.\pipe\wvds_crypto.
Verbindung und Hilfsfunktion
$pipe = [System.IO.Pipes.NamedPipeClientStream]::new('.', 'wvds_crypto', 'InOut') $pipe.Connect(5000) $utf8 = [System.Text.UTF8Encoding]::new($false) $reader = [System.IO.StreamReader]::new($pipe, $utf8) $writer = [System.IO.StreamWriter]::new($pipe, $utf8) $writer.NewLine = "`n"; $writer.AutoFlush = $true function Invoke-Crypto([hashtable] $request) { $writer.WriteLine(($request | ConvertTo-Json -Compress)) $reader.ReadLine() | ConvertFrom-Json }
Eine Anfrage ist eine Zeile, die Antwort ebenfalls. Die Verbindung bleibt für weitere Anfragen offen.
Signieren und prüfen
$key = Invoke-Crypto @{ operation = 'keygen'; request_id = 'k1'; algorithm = 'ML-DSA'; level = 'ML-DSA-65' } $message = [Convert]::ToBase64String($utf8.GetBytes('Messwert 42')) $sig = Invoke-Crypto @{ operation = 'ml_dsa_sign'; request_id = 's1'; key_id = $key.key_id; message = $message } $check = Invoke-Crypto @{ operation = 'ml_dsa_verify'; request_id = 'v1'; level = 'ML-DSA-65' public_key = $key.public_key; message = $message; signature = $sig.signature } $check.valid # True
keygen liefert key_id und den öffentlichen Schlüssel. Bewahren Sie den öffentlichen Schlüssel selbst
auf, wenn Signaturen nach einem Neustart des Dienstes noch prüfbar sein sollen. Eine ML-DSA-65-Signatur
ist 3309 Byte lang (signature_size).
Werten Sie bei ml_dsa_verify das Feld valid aus. Eine falsche Signatur ist kein Fehler: Die Antwort
hat success: true und valid: false.
Verschlüsseln und entschlüsseln
$aes = Invoke-Crypto @{ operation = 'keygen'; request_id = 'k2'; algorithm = 'AES-256-GCM' } $enc = Invoke-Crypto @{ operation = 'aes_encrypt'; request_id = 'e1'; key_id = $aes.key_id; plaintext = $message } $dec = Invoke-Crypto @{ operation = 'aes_decrypt'; request_id = 'd1'; key_id = $aes.key_id ciphertext = $enc.ciphertext; nonce = $enc.nonce; tag = $enc.tag } $utf8.GetString([Convert]::FromBase64String($dec.plaintext)) # Messwert 42
Der Dienst wählt die Nonce. Speichern oder übertragen Sie ciphertext, nonce und tag zusammen;
fehlt eines davon, lässt sich die Nachricht nicht mehr entschlüsseln. Optional bindet aad zusätzliche
Daten an das Chiffrat, die unverschlüsselt bleiben; geben Sie dann beim Entschlüsseln dasselbe aad an.
Schlüssel mit ML-KEM vereinbaren
Der Empfänger erzeugt ein Schlüsselpaar und gibt den öffentlichen Schlüssel weiter:
$kem = Invoke-Crypto @{ operation = 'keygen'; request_id = 'k3'; algorithm = 'ML-KEM-768' }
Der Sender kapselt mit diesem öffentlichen Schlüssel und schickt das Chiffrat an den Empfänger:
$cap = Invoke-Crypto @{ operation = 'ml_kem_encapsulate'; request_id = 'c1'; public_key = $kem.public_key; level = 'ML-KEM-768' }
Der Empfänger entkapselt:
$dcp = Invoke-Crypto @{ operation = 'ml_kem_decapsulate'; request_id = 'c2'; key_id = $kem.key_id; ciphertext = $cap.ciphertext } $cap.shared_secret -eq $dcp.shared_secret # True
Beide Seiten halten danach dasselbe Geheimnis von 32 Byte. Es verlässt den Dienst im Klartext, als
Base64 in der Antwort. Leiten Sie daraus mit hkdf einen Schlüssel für den eigentlichen Zweck ab und
behandeln Sie es auf der Client-Seite wie einen Schlüssel. Für ein hybrides Verfahren nach
BSI TR-02102-1 kombinieren Sie es zusätzlich mit einem klassischen Verfahren; siehe
Verfahren und Parametersätze.
Fehler erkennen
$r = Invoke-Crypto @{ operation = 'keygen'; request_id = 'k4'; algorithm = 'ML-KEM'; level = 'ML-KEM-999' } if (-not $r.success) { "$($r.error.code): $($r.error.message)" }
Ausgabe: UNSUPPORTED_ALGORITHM: Unsupported ML-KEM level: ML-KEM-999
Prüfen Sie success bei jeder Antwort. Die Bedeutung der Codes steht unter
Fehlercodes.
Verbindung schließen
$pipe.Dispose()