====== std.crypto.rand — Kryptografisch sichere Zufallszahlen ====== ''import std.crypto.rand;'' Kryptografisch sichere Zufallszahlen via ''getrandom(2)''-Syscall (Linux ≥ 3.17). Blockiert einmalig bis der Kernel-Entropie-Pool initialisiert ist, danach CSPRNG — kein ''/dev/urandom''-Dateideskriptor nötig. → [[lyx_-_programmiersprache:units:crypto|std.crypto Paket]] · [[lyx_-_programmiersprache:units:crypto:ecc|std.crypto.ecc]] · [[lyx_-_programmiersprache:units:hash|std.hash]] ---- ===== Konstanten ===== ^ Konstante ^ Wert ^ Bedeutung ^ | ''GRND_NONBLOCK'' | 1 | Gibt ''EAGAIN'' statt zu blockieren, wenn der Pool noch leer ist | | ''GRND_RANDOM'' | 2 | Liest aus ''/dev/random'' statt ''/dev/urandom'' (höhere Entropiequalität, kann blockieren) | Die Flags sind für direkten Einsatz mit ''RandBytes'' gedacht; ''RandBytesExact'', ''RandInt64'' und ''RandU32'' verwenden intern immer flags=0 (blockierend, CSPRNG). ---- ===== Funktionen ===== ^ Funktion ^ Signatur ^ Beschreibung ^ | ''RandBytes'' | ''(buf: int64, len: int64): int64'' | Bis zu ''len'' Bytes in ''buf'' — kann kurzlesen, Rückgabe: tatsächliche Byte-Anzahl oder negatives errno | | ''RandBytesExact'' | ''(buf: int64, len: int64): int64'' | Exakt ''len'' Bytes in ''buf'', wiederholt Syscall — Rückgabe: ''len'' oder negatives errno | | ''RandInt64'' | ''(): int64'' | Kryptografisch sicherer zufälliger int64; 0 bei Fehler | | ''RandU32'' | ''(): int64'' | Kryptografisch sicherer zufälliger uint32 (0..2³²−1) | ---- ===== Verwendung ===== ==== Schlüssel generieren ==== import std.crypto.rand; import std.alloc; fn GenAESKey(keyBuf: int64, keyLen: int64): int64 { // keyLen = 16 (AES-128) oder 32 (AES-256) return RandBytesExact(keyBuf, keyLen); } fn main(): int64 { var key: int64 := alloc(32); var rc: int64 := RandBytesExact(key, 32); if (rc < 0) { free(key, 32); return rc; } // key enthält 32 kryptografisch sichere Zufallsbytes free(key, 32); return 0; } ==== IV für AES-CBC erzeugen ==== import std.crypto.rand; import std.crypto.aes; import std.alloc; fn EncryptWithRandomIV(key: int64, data: int64, dataLen: int64, outBuf: int64, outIV: int64): int64 { // IV muss für jede Nachricht neu zufällig sein var rc: int64 := RandBytesExact(outIV, AES_BLOCK_SIZE); if (rc < 0) { return rc; } return AES256CBCEncrypt(key, outIV, data, dataLen, outBuf); } ==== Zufällige Ganzzahl ==== import std.crypto.rand; import std.io; fn main(): int64 { var v: int64 := RandInt64(); // v: volle 64-Bit-Zufallszahl, kryptografisch sicher var u: int64 := RandU32(); // u: 0..4294967295 return 0; } ==== Nicht-blockierend prüfen ==== import std.crypto.rand; fn TryGetRand(buf: int64, len: int64): int64 { // Gibt -EAGAIN zurück wenn Pool noch nicht bereit return sys_getrandom(buf, len, GRND_NONBLOCK); } ---- ===== Hinweise ===== * **Blockierung**: Beim ersten Aufruf nach dem Systemstart blockiert ''getrandom'' bis der Kernel-Entropie-Pool bereit ist. In Containern oder VMs kann das mehrere Sekunden dauern. * **RandInt64 gibt 0 bei Fehler**: Da 0 mit Wahrscheinlichkeit 2⁻⁶⁴ auch ein gültiger Wert ist, sollte bei sicherheitskritischem Code ''RandBytesExact'' statt ''RandInt64'' verwendet und der Rückgabewert geprüft werden. * **Kein /dev/urandom-FD**: Im Unterschied zu traditionellem Code braucht diese Unit keinen offenen Dateideskriptor — ideal für Sandboxed-Umgebungen mit reduziertem FD-Limit. * **GRND_RANDOM** ist selten sinnvoll: Der CSPRNG von ''getrandom'' (flags=0) ist für praktisch alle kryptografischen Zwecke ausreichend. ---- Letzte Aktualisierung: 2026-06-05