So werden die Zufallsstrings erzeugt
Jedes Zeichen wird einzeln aus den gewählten Zeichen gezogen, mit crypto.getRandomValues, dem kryptografisch sicheren Zufallszahlengenerator des Browsers, derselben Quelle wie bei Verschlüsselungsschlüsseln. Eine einfache Zufallszahl modulo der Zeichenanzahl würde manche Zeichen etwas wahrscheinlicher machen; diese Seite zieht neu, sobald ein Zufallswert in den ungleichen Rest fällt, sodass jedes Zeichen genau dieselbe Chance hat. Die Stärke eines Strings wird in Bit Entropie gemessen:
bits = length × log2(characters to choose from) 32 × log2(62) = 32 × 5.954 ≈ 190.5 bits
Jedes Bit verdoppelt die Zahl der Versuche, die ein Angreifer braucht. Ein Präfix wie sk_ fügt nichts hinzu, weil es in jedem String gleich ist; das Weglassen ähnlich aussehender Zeichen kostet ein wenig, weil weniger Zeichen zur Auswahl stehen. Math.random(), das viele schnelle Generatoren nutzen, ist nicht sicher: Seine Ausgabe lässt sich aus früheren Werten vorhersagen.
Beispiel
Ein 32 Zeichen langer String aus Buchstaben und Ziffern hat für jedes Zeichen 62 Möglichkeiten, also 32 × log2(62) ≈ 190,5 Bit: weit jenseits des Erratbaren. 32 Hex-Zeichen tragen 32 × 4 = 128 Bit, so viel wie 16 zufällige Bytes. Base64url nutzt 64 Zeichen mit je 6 Bit, also fassen 43 davon 258 Bit, was 32 zufällige Bytes ergeben. Ein 6-stelliger Code hat nur eine Million Möglichkeiten (19,9 Bit): In einer Liste von 500 solchen Codes liegt die Chance, dass zwei gleich sind, schon bei etwa 11,7 %.
Auf dem Server
Um Zufallsstrings auf einem Linux-Server oder in einem Deploy-Skript zu erzeugen, nutzen Sie die sichere Zufallsquelle des Systems, /dev/urandom, über openssl oder tr:
openssl rand -hex 16 # 32 hex characters
openssl rand -base64 32 | tr '+/' '-_' | tr -d '='
head -c 500 /dev/urandom | LC_ALL=C tr -dc 'A-Za-z0-9' | head -c 32Fragen
Sind diese Zufallsstrings sicher?
Ja. Sie stammen von crypto.getRandomValues, dem kryptografisch sicheren Zufallszahlengenerator Ihres Browsers, und jedes Zeichen wird ohne Verzerrung gezogen. Sie werden auf Ihrem Gerät erzeugt und nie an einen Server gesendet, sodass niemand sonst sie sieht. Für Schlüssel und Tokens nehmen Sie mindestens 128 Bit Entropie, etwa 22 Buchstaben und Ziffern oder 32 Hex-Zeichen.
Wie erzeuge ich einen zufälligen String mit 32 Zeichen?
Stellen Sie die Länge auf 32 (der Standard) und wählen Sie die Zeichen: Buchstaben und Ziffern ergeben etwa 190 Bit, Hex genau 128. Auf einem Server gibt openssl rand -hex 16 32 zufällige Hex-Zeichen aus. In Python: secrets.token_hex(16), oder secrets.token_urlsafe(24) für 32 Base64url-Zeichen.
Wie lang sollte ein zufälliger API-Schlüssel oder ein Token sein?
Mindestens 128 Bit Entropie, damit er sich auch bei Milliarden Versuchen pro Sekunde nicht erraten lässt. Das sind 22 Buchstaben und Ziffern, 32 Hex-Zeichen oder 22 Base64url-Zeichen. Viele Dienste nutzen 32 bis 40 Zeichen mit einem Präfix wie sk_, das sagt, wofür der Schlüssel ist, was Secret-Scannern hilft, geleakte Schlüssel zu finden.
Was ist der Unterschied zwischen Hex- und Base64url-Strings?
Hex nutzt 16 Zeichen (0–9 und a–f), jedes trägt also 4 Bit. Base64url nutzt 64 (Buchstaben, Ziffern, - und _), jedes trägt also 6 Bit, und der String ist bei gleicher Stärke ein Drittel kürzer. Beide sind in URLs, Dateinamen und Konfigurationsdateien sicher. Hex ist leichter zu lesen, Base64url kompakter.
Können zwei erzeugte Strings gleich sein?
Bei ausreichender Länge praktisch nie: Bei 128-Bit-Strings bräuchten Sie etwa 2^64 davon, 18 Trillionen, bevor eine Wiederholung wahrscheinlich wird. Kurze Strings wiederholen sich früher, als man denkt, nach dem Geburtstagsproblem: Unter 500 sechsstelligen Codes sind in etwa 12 % der Fälle zwei gleich. Die Seite warnt Sie, wenn eine Wiederholung in Ihrer Liste wahrscheinlich ist.