====== Kryptographie in Lyx ======
Dieser Guide erklärt alle kryptografischen Units der Lyx-Standardbibliothek, vergleicht ähnliche Optionen und gibt klare Empfehlungen, was wann verwendet werden sollte.
→ [[lyx_-_programmiersprache:units:crypto|std.crypto (Unit-Referenz)]] · [[lyx_-_programmiersprache:guides:welche-unit|Welche Unit?]] · [[lyx_-_programmiersprache:units|Standard Library]]
----
===== Alle Krypto-Units im Überblick =====
^ Unit ^ Kategorie ^ Empfehlung ^
| [[lyx_-_programmiersprache:units:crypto:aes|std.crypto.aes]] | Symmetrische Verschlüsselung | Standardwahl; NIST-zertifiziert |
| [[lyx_-_programmiersprache:units:crypto:pqc:dadq|std.crypto.pqc.dadq]] | Sym. Auth. Cipher (experimentell) | Authentifizierung ohne separaten MAC; Quantum-aware |
| [[lyx_-_programmiersprache:units:crypto:sha256|std.crypto.sha256]] | Kryptografischer Hash | Standardwahl für neue Projekte |
| [[lyx_-_programmiersprache:units:crypto:hmac|std.crypto.hmac]] | MAC / Integrität | AES-CBC absichern; API-Authentifizierung |
| [[lyx_-_programmiersprache:units:crypto:ecc|std.crypto.ecc]] | Digitale Signatur | Einzige Signatur-Option in std.crypto |
| [[lyx_-_programmiersprache:units:crypto:rand|std.crypto.rand]] | CSPRNG | Für alle Schlüssel und IVs |
| [[lyx_-_programmiersprache:units:crypto:sha1|std.crypto.sha1]] | Legacy-Hash | Nur für vorgeschriebene Protokolle |
| [[lyx_-_programmiersprache:units:crypto:md5|std.crypto.md5]] | Legacy-Hash | Nur für vorgeschriebene Protokolle |
----
===== Symmetrische Verschlüsselung: AES vs DADQ =====
Die beiden Optionen für symmetrische Verschlüsselung unterscheiden sich fundamental:
^ Eigenschaft ^ AES-CBC (std.crypto.aes) ^ DADQ-SYM (std.crypto.pqc.dadq) ^
| Standard | NIST FIPS 197, AES — weltweit anerkannt | Experimentell, kein NIST-Standard |
| Authentifizierung | **Nein** — nur Vertraulichkeit | **Ja** — integrierter Integrity-Check |
| Quantum-Sicherheit | AES-128: 64-Bit; AES-256: 128-Bit (Grover) | 128-Bit (Grover-Bound 2¹²⁸) |
| Ciphertext-Overhead | 0 (Blockgröße 16 Bytes, PKCS#7-Padding) | 64 Bytes (commit + hash_mr) |
| Key-Größe | AES-128: 16B; AES-256: 32B | master_seed: 32B; T_pub: 65536B |
| Performance | Schnell (Tabellen-basiert) | Langsamer (große Tabelle, DRBG-Expansion) |
| Compliance (DO-178C, FIPS) | Ja | Nein |
| Reines Lyx, keine ext. Deps | Ja | Ja |
**Wann AES-CBC:**
* Compliance-Anforderungen (FIPS, DO-178C, ISO 27001)
* Interoperabilität mit anderen Systemen (TLS, Dateiverschlüsselung)
* Performance kritisch
* Bekannte, auditierte Konstruktion bevorzugt
**Wann DADQ-SYM / DADQ-FO:**
* Authentifizierte Verschlüsselung ohne separaten MAC-Schritt gewünscht
* Kein externer Standard erforderlich
* Quantum-Aspekte relevant, aber ML-KEM nicht verfügbar/nötig
* Reine Lyx-Implementierung ohne Einschränkung durch Patente oder Lizenzfragen
**Kombination:** AES-CBC ist **nicht authentifiziert** — für Manipulationsschutz immer ''std.crypto.hmac'' (HMAC-SHA256) nachschalten:
// Encrypt-then-MAC (Standardmuster für AES-CBC)
AES256CBCEncrypt(key, iv, plain, plain_len, cipher);
HMAC_SHA256(mac_key, cipher, cipher_len, mac);
// Übertragen: iv || cipher || mac
DADQ übernimmt Verschlüsselung und MAC in einem Schritt.
----
===== Die drei DADQ-Modi =====
DADQ hat drei Nutzungsmodi mit unterschiedlichen Sicherheitsgarantien:
^ Modus ^ Funktionen ^ Sicherheit ^ Wann ^
| **Basis** | ''dadqEnc / dadqDec'' | IND-CPA | Wenn T_pub bereits vorhanden / weitergegeben |
| **Sym** | ''dadqSymEnc / dadqSymDec'' | IND-CPA | Rein symmetrisch — T_pub bleibt intern, nie öffentlich |
| **FO** | ''dadqFOEnc / dadqFODec'' | IND-CCA2 | Neue Anwendungen; stärkste Garantie |
**Basis-Modus** (''dadqEnc''): Verschlüsselt mit T_pub (65536-Byte-Tabelle als „öffentlicher" Schlüssel). Geeignet wenn beide Parteien T_pub kennen. Randomisiert — unterschiedliche Ciphertexte für gleiche Klartexte.
**Sym-Modus** (''dadqSymEnc''): T_pub wird intern abgeleitet und nie weitergegeben — schützt dadurch gegen den strukturellen col_inv-Angriff auf T_pub. Empfohlen gegenüber Basis-Modus wenn keine Kompatibilität zu Basis-API nötig.
**FO-Modus** (''dadqFOEnc''): Fujisaki-Okamoto Transform — r_seed wird deterministisch aus dem Klartext via HMAC berechnet. Dadurch ist Wiederverschlüsselung möglich und CCA2-Sicherheit beweisbar. Der Dec-Check ist nicht-tautologisch (``HMAC(key_fo, m_dec) == r_seed``). **Empfohlen für alle neuen Anwendungen.**
// FO-Modus: einfachste sichere Variante
var sk_fo: int64 := alloc(DADQ_FO_SK_LEN);
dadqFOKeyGenRand(sk_fo); // interner CSPRNG-Seed, wird nach Ableitung gelöscht
dadqFOEnc(sk_fo, m, m_len, c);
var rc: int64 := dadqFODec(sk_fo, c, c_len, m_out); // -1 bei Manipulation
dadqZeroize(sk_fo, DADQ_FO_SK_LEN);
----
===== Hashfunktionen: SHA-256 vs SHA-1 vs MD5 =====
^ Eigenschaft ^ SHA-256 ^ SHA-1 ^ MD5 ^
| Digest-Größe | 256 Bit (32 Bytes) | 160 Bit (20 Bytes) | 128 Bit (16 Bytes) |
| Kollisionen bekannt | Nein | **Ja** (SHAttered 2017) | **Ja** (seit 2004) |
| Präimage-Resistenz | Stark | Reduziert | Stark geschwächt |
| NIST-Status | Empfohlen (FIPS 180-4) | Deprecated | Nicht für Krypto |
| Quantum (Grover) | 128-Bit | 80-Bit | 64-Bit |
**SHA-256 verwenden für:** Datenintegrität, HMAC-Basis, digitale Signaturen, Schlüsselableitung, Passwort-Hashing (mit salt).
**SHA-1 nur für:** MySQL ''mysql_native_password''-Authentifizierung (Protokoll erzwingt es), Git-Objektadressen (Legacy-Kompatibilität).
**MD5 nur für:** HTTP Digest Authentication (RFC 2617 schreibt MD5 vor), andere Protokolle die explizit MD5 verlangen.
**Faustregel:** Wenn das Protokoll keinen bestimmten Hash vorschreibt → immer SHA-256.
----
===== Integrität und Authentifizierung =====
Drei Wege für Integrität und Authentifizierung:
**1. HMAC-SHA256** (''std.crypto.hmac''):
Für Nachrichten-Authentifizierung wenn Verschlüsselung separat erfolgt oder gar nicht benötigt wird.
HMAC_SHA256(key, msg, msg_len, mac_out); // mac_out = 32 Bytes
**2. AES-CBC + HMAC (Encrypt-then-MAC)**:
Industriestandard-Muster. Beide Schlüssel sollten unabhängig voneinander sein.
**3. DADQ-FO** (integrierter Ansatz):
Ein einziger Schlüssel (sk_fo, 608 Bytes), ein Aufruf — Verschlüsselung und Authentifizierung kombiniert.
^ Kriterium ^ HMAC allein ^ AES + HMAC ^ DADQ-FO ^
| Nur Integrität (kein Ciphertext) | Ja | Nein | Nein |
| Vertraulichkeit + Integrität | Nein | Ja | Ja |
| NIST-Compliance | Ja | Ja | Nein |
| Quantum-Hardening | Nein | Teilweise (AES-256) | Ja (128-Bit) |
| API-Einfachheit | 1 Fn | 2 Fn + IV | 1 Fn |
----
===== Digitale Signaturen =====
Aktuell steht in ''std.crypto'' nur **secp256k1 ECDSA** (''std.crypto.ecc'') zur Verfügung.
import std.crypto.ecc;
ECCGenKey(pk, sk); // Schlüsselpaar erzeugen
ECDSASign(sk, hash, sig); // hash = SHA256 des Dokuments
ECDSAVerify(pk, hash, sig); // 1 = gültig, 0 = ungültig
Hinweise:
* Immer **SHA-256** des Dokuments signieren, nie den Rohtext.
* secp256k1 ist die Bitcoin-Kurve — weitverbreitet, gut auditiert.
* Kein Ed25519 oder ECDSA-P256 in std.crypto (nur secp256k1).
* Post-Quantum-Signaturen: noch nicht in std.crypto verfügbar — für PQC-Signaturen → ML-DSA (FIPS 204, extern) oder Hybrid-Schema.
----
===== Sichere Zufallszahlen =====
Alle kryptografischen Schlüssel, IVs und Nonces müssen aus ''std.crypto.rand'' stammen:
import std.crypto.rand;
RandBytesExact(buf, n); // genau n Bytes, blockierend (getrandom(2))
RandBytes(buf, n); // bis zu n Bytes
var n: int64 := RandInt64(); // zufälliges int64
var u: int64 := RandU32(); // zufälliges uint32
**Niemals** ''std.math.random'' oder ähnliche nicht-kryptografische Zufallsgeneratoren für kryptografische Zwecke verwenden.
----
===== Entscheidungsguide =====
^ Ich will … ^ Unit / Funktion ^
| Daten verschlüsseln (Standard, NIST) | ''std.crypto.aes'' → ''AES256CBCEncrypt'' |
| Daten verschlüsseln + authentifizieren (NIST) | ''std.crypto.aes'' + ''std.crypto.hmac'' |
| Auth. Verschlüsselung (Lyx-nativ, Quantum) | ''std.crypto.pqc.dadq'' → ''dadqFOEnc'' |
| Hash für Integrität / Signaturen | ''std.crypto.sha256'' → ''SHA256'' |
| Nachricht authentifizieren (MAC) | ''std.crypto.hmac'' → ''HMAC_SHA256'' |
| Digitale Signatur erzeugen | ''std.crypto.ecc'' → ''ECDSASign'' |
| Digitale Signatur prüfen | ''std.crypto.ecc'' → ''ECDSAVerify'' |
| Kryptografisch sicheren Schlüssel erzeugen | ''std.crypto.rand'' → ''RandBytesExact'' |
| Zufälligen AES-IV erzeugen | ''std.crypto.rand'' → ''RandBytesExact(iv, 16)'' |
| MySQL-Authentifizierung | ''std.crypto.sha1'' → ''SHA1MySQLNativePassword'' |
| HTTP Digest Auth / alte Protokolle | ''std.crypto.md5'' → ''MD5'' |
| DADQ-Schlüssel sicher löschen | ''std.crypto.pqc.dadq'' → ''dadqZeroize'' |
| Schwachen DADQ-Seed erkennen | ''std.crypto.pqc.dadq'' → ''dadqValidateSeed'' |
----
===== Sicherheitsregeln auf einen Blick =====
- **MD5 und SHA-1** nicht für neue kryptografische Zwecke — nur wenn das Protokoll es vorschreibt.
- **AES-CBC ist nicht authentifiziert** — immer HMAC nachschalten, oder DADQ-FO verwenden.
- **IV muss einmalig und zufällig sein** — niemals einen festen IV verwenden.
- **ECDSA-Nonces** darf man nicht selbst setzen — ''std.crypto.ecc'' generiert intern.
- **DADQ ist experimentell** — nicht für FIPS/DO-178C/ISO-27001-zertifizierte Projekte.
- **Schlüssel nach Verwendung löschen** — ''dadqZeroize'' oder manuelle ''poke8''-Schleife.
- Alle kryptografischen Zufallswerte nur aus ''std.crypto.rand''.
Letzte Aktualisierung: 2026-06-08