Der Zufallsgenerator

So funktioniert crypto.getRandomValues()

crypto.getRandomValues() ist eine Methode aus dem Web Crypto API, die kryptografisch sichere Zufallszahlen erzeugt. Im Gegensatz zu Math.random() nutzt sie Entropiequellen des Betriebssystems und eignet sich dadurch sowohl für sicherheitskritische Anwendungen als auch für alltägliche Generatoren.

Echte Zufälligkeit ist schwerer zu erreichen, als es aussieht
Echte Zufälligkeit ist schwerer zu erreichen, als es aussieht
Inhaltsverzeichnis

Was ist crypto.getRandomValues() und wie funktioniert es?

crypto.getRandomValues() ist Teil des Web Crypto API, das in modernen Browsern und in Node.js integriert ist. Im Gegensatz zu Math.random(), das einen deterministischen Pseudozufallszahlengenerator (PRNG) verwendet, füllt crypto.getRandomValues() ein Typed Array mit kryptografisch starken Zufallswerten aus dem Entropiepool des Betriebssystems.

Auf den meisten Betriebssystemen wird diese Entropie aus Quellen wie Hardware-Interrupts, Mausbewegungen, Tastaturtimings und ähnlichen unvorhersehbaren Ereignissen gewonnen. Da die Werte aus physischer Zufälligkeit und nicht aus einem festen Algorithmus stammen, sind sie deutlich schwerer vorherzusagen oder zu reproduzieren.

Die Methode erwartet ein Typed Array — zum Beispiel Uint8Array, Uint16Array oder Uint32Array — und füllt es mit Zufallswerten:

const array = new Uint32Array(1)

crypto.getRandomValues(array)
console.log(array[0]) // Eine kryptografisch zufällige 32-Bit-Ganzzahl

Warum crypto.getRandomValues() stärker ist als Math.random()

Der zentrale Unterschied liegt in der Vorhersagbarkeit:

  • Math.random() verwendet einen Algorithmus mit Startwert (Seed). Grundsätzlich lässt sich die Folge vorhersagen, wenn der Seed oder genügend Ausgabewerte bekannt sind. Browser stellen den Seed nicht bereit, aber der zugrunde liegende PRNG ist nicht für Sicherheitszwecke entwickelt.

  • crypto.getRandomValues() greift auf den Entropiepool des Systems zu, der kontinuierlich durch Hardware-Ereignisse ergänzt wird. Die Ausgabe ohne Zugriff auf die zugrunde liegende Hardware vorherzusagen, ist praktisch unmöglich.

Für Anwendungen wie das Erzeugen von Tokens, Identifikatoren oder allem, bei dem Vorhersagbarkeit vermieden werden muss, ist crypto.getRandomValues() die richtige Wahl. Für Spiele, Animationen oder visuelle Variation, bei denen Sicherheit keine Rolle spielt, bleibt Math.random() weiterhin eine gute Option.

Lies mehr darüber, wie Math.random() funktioniert und warum wir uns später davon verabschiedet haben.

Wie Der Zufallsgenerator crypto.getRandomValues() verwendet

Der Zufallsgenerator wurde ursprünglich mit Math.random() gebaut. Für viele Zwecke funktioniert das gut, ist aber nicht kryptografisch sicher — die Werte könnten theoretisch vorhergesagt werden, wenn der interne PRNG-Zustand bekannt wäre.

Inzwischen haben wir die gesamte Zufallszahlengenerierung auf crypto.getRandomValues() umgestellt. Dadurch erhalten alle Generatoren — vom Zufallszahlengenerator bis zu thematischen Auswahlen und kleinen Entscheidungshilfen — eine stärkere Grundlage für Zufälligkeit.

Intern verwenden alle Generatoren eine gemeinsame Hilfsfunktion namens cryptoRandom(). Sie kapselt crypto.getRandomValues() und liefert eine Fließkommazahl im Bereich [0, 1) — dieselbe Schnittstelle wie Math.random(). Dadurch ist sie einfach als direkter Ersatz nutzbar:

const cryptoRandom = () => {
  if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
    const array = new Uint32Array(1)

    crypto.getRandomValues(array)

    return array[0] / 2 ** 32
  }

  return Math.random()
}

Durch die Division der zufälligen 32-Bit-Ganzzahl durch 2^32 (4 294 967 296) erhalten wir eine Zahl im Bereich [0, 1), genau wie bei Math.random(). Der Fallback auf Math.random() bleibt für Umgebungen ohne Web Crypto API enthalten, was in modernen Browsern allerdings sehr selten ist.

Diese cryptoRandom()-Funktion wird anschließend verwendet, um Hilfsfunktionen auf höherer Ebene zu bauen:

// Wähle ein zufälliges Element aus einem Array
const random = (array) => array[Math.floor(cryptoRandom() * array.length)]

// Generiere eine zufällige Ganzzahl in einem Bereich
const randomInRange = (min, max) =>
  Math.floor(cryptoRandom() * (max - min + 1)) + min

Browser-Unterstützung und Verfügbarkeit

crypto.getRandomValues() wird von allen modernen Browsern unterstützt und ist seit vielen Jahren verfügbar. In Node.js (ab Version 15+) steht die Methode ebenfalls als globalThis.crypto.getRandomValues() zur Verfügung.

Lies mehr über die Methode auf Mozillas Website MDN.

Übersetzungen

Zuletzt aktualisiert von Vincent Lejtzén.