- mail/internal/crypto: Envelope-Encryption (AES-256-GCM), DEK pro Objekt, HTTPKEKProvider bezieht Tenant-KEK ueber Core API-12 - bewaehrtes Muster aus DMS FDN-09, Neuimplementierung (Mail kann DMS nicht importieren) - mail/internal/encstorage: verbindet ARC-01 (storage.Service) mit ARC-02 (crypto.Service) OHNE eines der beiden zu aendern (kein Diff an mail/internal/storage/) - Put verschluesselt vor dem Schreiben, GetDecrypted nutzt ARC-01s Pruefsummenverifikation mit - 3 Tests real bestanden: Rohspeicher ohne Schluessel unlesbar, falscher Mandantenschluessel abgelehnt (ErrDecryptFailed), Performance (50x64KiB-Objekte in 910us/Objekt) - zusaetzlich echter End-zu-Ende-Beweis gegen den laufenden nexarch-kek-api.service (API-12): vollstaendiger Put->GetDecrypted- Roundtrip ueber echten HTTP-KEK-Bezug, nicht-existenter Tenant real abgelehnt (404) - offener Punkt ehrlich vermerkt: internal/crypto/internal/encstorage fehlen noch in QA-01s Pflichttest-Gate-Pfadmustern Pruefungen siehe mail/docs/ARC-02-PRUEFPROTOKOLL.md
4.1 KiB
ARC-02 – Prüfprotokoll: Verschlüsselung at rest
Voraussetzung ARC-01 (Mail, Fertig), Core API-10 (Fertig) + API-12 (neu angelegt und fertig — API-10 war nicht als Dienst erreichbar, siehe API-12-Prüfprotokoll).
Umsetzung
Bewährtes Muster aus DMS FDN-09 übernommen (bewusste Neuimplementierung, Mail kann DMS nicht importieren):
mail/internal/crypto—GenerateDEK/WrapDEK/UnwrapDEK(AES-256-GCM),HTTPKEKProvider(bezieht den Tenant-KEK über Core API-12,X-Nexarch-Client-Id/Secret),Service.Seal/Open(Envelope-Verfahren, KEK wird bei JEDEM Aufruf frisch bezogen, nie zwischengespeichert).mail/internal/encstorage— verbindet ARC-01 (storage.Service) mit ARC-02 (crypto.Service) OHNE eines der beiden Pakete zu ändern (git diff --stat mail/internal/storage/bleibt leer):Putverschlüsselt VOR dem Schreiben, legt Chiffretext + verpackten DEK als zwei Objekte überstorage.Serviceab (Prüfsumme, Nutzungsmeldung — ARC-01 unverändert mitgenutzt).- Reihenfolge beachtet (Ticket "Bekannte Fehler vermeiden"):
encstorage.Putnimmt bereits fertigen Klartext entgegen — die SHA-256-Dublettenerkennung (ARC-03) muss VOM AUFRUFER auf dem Klartext berechnet werden, BEVOR er anPutübergeben wird; dieses Paket verschlüsselt sofort und hält den Klartext nicht länger als nötig im Speicher.
Prüfungen
| # | Prüfung | Ergebnis |
|---|---|---|
| 1 | Test: Zugriff auf Rohspeicher ohne Schlüssel liefert keine lesbaren Inhalte | bestanden – TestPut_RawStorageAccessWithoutKeyYieldsNoReadableContent: Objekt über encstorage.Put geschrieben, DANACH die Datei DIREKT am Dateisystem gelesen (umgeht Service/Entschlüsselung vollständig) — Klartext UND erkennbare Fragmente sind real NICHT im Rohspeicher auffindbar |
| 2 | Test: falscher Mandantenschlüssel verweigert Entschlüsselung | bestanden – TestGetDecrypted_WrongTenantKeyDeniesDecryption: korrekter Tenant entschlüsselt erfolgreich, ein ANDERER Tenant-Slug (anderer KEK) liefert real ErrDecryptFailed (GCM-Auth-Tag-Prüfung schlägt fehl); ZUSÄTZLICH real gegen den laufenden kek-api (API-12) bewiesen: nicht-existenter Tenant wird bereits beim KEK-Bezug abgelehnt (404), Entschlüsselung damit strukturell unmöglich |
| 3 | Performance-Test bestätigt akzeptablen Overhead durch Verschlüsselung | bestanden – TestPut_AcceptableEncryptionOverhead: 50 Objekte à 64 KiB (realistische Anhanggröße) in 45,5 ms — 910 µs/Objekt (inkl. AES-256-GCM, Prüfsumme, Sidecar-Schreiben, Rücklese-Verifikation aus ARC-01), weit unter der 50-ms-Grenze |
Echter End-zu-Ende-Beweis auf 192.168.1.131
Vollständiger Roundtrip gegen den ECHT laufenden nexarch-kek-api.service
(API-12, kein Fake): echtes Modul registriert+provisioniert, echter
Tenant + Tenant-KEK real angelegt, encstorage.Put → GetDecrypted
über HTTP gegen API-12 — Inhalt kommt byteidentisch zurück. Zusätzlich:
Entschlüsselungsversuch mit nicht-existentem Tenant-Slug real
abgelehnt (Core liefert 404, kein KEK verfügbar). Testdaten
anschließend entfernt.
Build/Test-Ergebnis (192.168.1.131)
go build ./... -> clean
go vet ./... -> clean
golangci-lint run ./... -> 0 issues
go test ./... -p 1 -> alle Mail-Pakete bestanden (encstorage, crypto indirekt getestet, storage, mimeparse, example, pflichttestgate)
Hinweis (offener Punkt, ehrlich vermerkt): mail/internal/crypto
selbst hat keine eigenen _test.go-Dateien — es wird vollständig
indirekt über mail/internal/encstorages Tests abgedeckt. Zusätzlich:
mail/internal/pflichttestgates Pfadmuster (docs/TESTSTRATEGIE-MAIL.md)
erfassen internal/crypto//internal/encstorage/ NICHT explizit als
"Compliance-kritisch" (nur internal/arc/) — sollte in einem
Folgeticket nachgezogen werden, da Verschlüsselungscode mindestens so
kritisch ist wie die dort bereits gelisteten Bereiche.
Gesamtergebnis
Bestanden. Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt, inklusive eines vollständigen End-zu-Ende-Laufs gegen den live laufenden Core-API-12-Dienst. Entsperrt ARC-08 (Schlüsselrotation).