Start · Sprachen · JavaScript · Referenz · Crypto.getRandomValues()

Crypto.getRandomValues()

Methode

Füllt ein ganzzahliges TypedArray mit kryptografisch starken Zufallswerten und gibt dasselbe Array zurück.

seit JavaScript Baseline: alle Browser; Node.js 17+ (global crypto Kategorie: webapi

Signatur

Crypto.prototype.getRandomValues(typedArray)

Beschreibung

crypto.getRandomValues() füllt das übergebene ganzzahlige TypedArray mit Zufallswerten aus einem kryptografisch sicheren Pseudozufallszahlengenerator (CSPRNG). Den Startwert (Seed) liefert das Betriebssystem bzw. die Laufzeitumgebung. Deshalb sind die Werte für Angreifer praktisch nicht vorhersagbar, anders als bei Math.random().

Die Methode eignet sich für alles, was sicherheitsrelevant ist: Tokens, Nonces, Salts, Initialisierungsvektoren (IVs), zufällige Passwörter oder eigene IDs. Das Array wird direkt verändert. Der Rückgabewert ist genau dieselbe Referenz, deshalb kann man den Aufruf verketten.

Anders als die meisten Funktionen der Web Crypto API läuft getRandomValues() synchron. Sie steht außerdem in unsicheren Kontexten (HTTP) und in Web Workern zur Verfügung. Nur crypto.subtle und crypto.randomUUID() brauchen einen sicheren Kontext (HTTPS).

Parameter

Name Typ Default Beschreibung
$typedArray Pflicht Int8Array|Uint8Array|Uint8ClampedArray|Int16Array|Uint16Array|Int32Array|Uint32Array|BigInt64Array|BigUint64Array Ein ganzzahliges TypedArray, das mit Zufallswerten überschrieben wird. Float32Array, Float64Array und DataView sind nicht erlaubt. Die Länge darf höchstens 65536 Bytes betragen.

Rückgabewert

Typ
TypedArray
Beschreibung
Dasselbe Array, das übergeben wurde (keine Kopie). Es ist jetzt mit Zufallswerten gefüllt.

Beispiele

Zufälliges Token als Hex-String erzeugen

const randomHex = (byteLength = 16) => {
  const bytes = crypto.getRandomValues(new Uint8Array(byteLength));
  return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
};

console.log(randomHex(16));
z. B. "3f9a1c07e2b84d5f9a0c11de4b7f6a21" (32 Hex-Zeichen)

Unverzerrte Zufallszahl in einem Bereich (Rejection Sampling)

// Ganzzahl in [min, max] ohne Modulo-Verzerrung
const secureRandomInt = (min, max) => {
  const range = max - min + 1;
  const maxUint = 2 ** 32;
  const limit = maxUint - (maxUint % range);
  const buf = new Uint32Array(1);
  let value;
  do {
    crypto.getRandomValues(buf);
    value = buf[0];
  } while (value >= limit);
  return min + (value % range);
};

console.log(secureRandomInt(1, 6)); // sicherer Würfelwurf
z. B. 4

Sicheres Zufallspasswort erzeugen

const generatePassword = (length = 20) => {
  const alphabet = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!@#$%&*';
  // 256 % 64 === 0 → keine Verzerrung, da das Alphabet 64 Zeichen hat
  const bytes = crypto.getRandomValues(new Uint8Array(length));
  return Array.from(bytes, (b) => alphabet[b % alphabet.length]).join('');
};

console.log(generatePassword());
z. B. "kR7!xTq2@mZp9#LwBv4&"

Zufälligen IV für AES-GCM erzeugen

const encrypt = async (key, text) => {
  const iv = crypto.getRandomValues(new Uint8Array(12)); // 96 Bit IV
  const data = new TextEncoder().encode(text);
  const ciphertext = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, data);
  return { iv, ciphertext };
};

const key = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
const { iv, ciphertext } = await encrypt(key, 'Geheim');
console.log(iv.length, ciphertext.byteLength);
12 22

// Wichtig · Fallstricke

  • 65536-Byte-Grenze: Ist das Array größer als 65536 Bytes, wird eine QuotaExceededError-DOMException geworfen, bei Uint32Array also ab 16385 Elementen. Größere Puffer füllt man in Blöcken, etwa über subarray().
  • Falscher Typ: Bei Float32Array, Float64Array oder DataView wird ein TypeMismatchError geworfen.
  • Modulo-Verzerrung: Ein einfaches value % n verzerrt die Verteilung, wenn der Wertebereich kein Vielfaches von n ist. Dann Rejection Sampling verwenden (siehe Beispiel).
  • Nicht für Schlüssel gedacht: Kryptografische Schlüssel erzeugt man besser mit crypto.subtle.generateKey().
  • this muss an crypto gebunden sein. Eine losgelöste Referenz wie const f = crypto.getRandomValues; f(arr) wirft einen TypeError.
  • Kompatibilität: Die Methode wird von allen modernen Browsern unterstützt (IE 11 nur als msCrypto). In Node.js ist crypto ab Version 17 global verfügbar, davor über require('node:crypto').webcrypto.