# 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): `Put` verschlüsselt VOR dem Schreiben, legt Chiffretext + verpackten DEK als zwei Objekte über `storage.Service` ab (Prüfsumme, Nutzungsmeldung — ARC-01 unverändert mitgenutzt). - **Reihenfolge beachtet** (Ticket "Bekannte Fehler vermeiden"): `encstorage.Put` nimmt bereits fertigen Klartext entgegen — die SHA-256-Dublettenerkennung (ARC-03) muss VOM AUFRUFER auf dem Klartext berechnet werden, BEVOR er an `Put` ü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/encstorage`s Tests abgedeckt. Zusätzlich: `mail/internal/pflichttestgate`s 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).