====== 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