Passsatz-Generator
Würfelt eine Kette aus zufälligen Wörtern — leichter zu merken als Zeichensalat und trotzdem sehr stark.
Ein Passsatz ist ein Passwort aus mehreren zufällig gewürfelten Wörtern, zum Beispiel Kranich-Melone-Uhrwerk-Distel. Die Idee stammt aus dem sogenannten Diceware-Verfahren, bei dem man Wörter mit echten Würfeln aus einer nummerierten Liste zieht. Der Vorteil gegenüber einem Zeichensalat wie x7#Qp2!v: Ein Passsatz lässt sich als Bild merken — ein Kranich, der eine Melone trägt — und ist trotzdem stärker, weil er viel länger ist.
Stellt unten ein, aus wie vielen Wörtern der Passsatz bestehen soll und womit die Wörter verbunden werden. Auf Wunsch hängt das Script eine zweistellige Zahl an, weil manche Anmeldeformulare stur eine Ziffer verlangen. Ein Klick auf „Würfeln" erzeugt einen neuen Vorschlag; unter dem Ergebnis steht, wie stark er rechnerisch ist.
Die Wortliste enthält genau 128 deutsche Hauptwörter ohne Umlaute — das macht das Abtippen auf fremden Tastaturen einfacher. 128 Möglichkeiten je Wort entsprechen genau 7 Bit, vier Wörter ergeben also 28 Bit, sechs Wörter 42 Bit. Wichtig ist dabei, dass die Wörter wirklich zufällig gezogen werden und nicht von euch ausgesucht: Ein selbst ausgedachter „zufälliger" Satz ist es nie. Deshalb benutzt das Script crypto.getRandomValues, den kryptografisch tauglichen Zufallsgenerator des Browsers, und nicht das bequemere Math.random.
Wie stark euer Vorschlag ist, könnt ihr im Passwort-Stärke-Prüfer gegenrechnen. Wer lieber klassischen Zeichensalat möchte, nimmt den Passwortgenerator; für reine Ziffernfolgen gibt es den PIN-Generator.
Der Passsatz entsteht in eurem Browser und wird nirgends übertragen oder gespeichert.
So funktioniert das Script
Das Script hat drei Teile: eine Wortliste, einen sauberen Zufallsgenerator und die Funktion, die daraus einen Satz baut. Der interessanteste Teil ist der Zufall — genau da machen selbstgebaute Passwortgeneratoren die meisten Fehler.
const puffer = new Uint8Array(1);
crypto.getRandomValues(puffer);
Uint8Array ist ein Speicherbereich für ganze Zahlen von 0 bis 255 — hier mit Platz für genau eine. crypto.getRandomValues füllt ihn mit Zufall aus der Quelle des Betriebssystems. Das ist etwas anderes als Math.random(): Dessen Zahlenfolge ist zwar gut durchmischt, aber berechenbar und für Sicherheitszwecke ausdrücklich nicht gedacht.
const groesstesVielfaches = Math.floor(256 / grenze) * grenze;
do {
crypto.getRandomValues(puffer);
wert = puffer[0];
} while (wert >= groesstesVielfaches);
return wert % grenze;
Hier steckt eine Feinheit, die man leicht übersieht. Der naheliegende Weg wäre wert % grenze ohne die Schleife. Bei einer Grenze von 100 würden die Zahlen 0 bis 55 dann aber dreimal getroffen (0, 100, 200) und die Zahlen 56 bis 99 nur zweimal — die kleinen Zahlen kämen häufiger heraus. Deshalb wird jeder Wert oberhalb des größten durch grenze teilbaren Vielfachen verworfen und neu gewürfelt. Das Verfahren heißt Verwerfungsmethode. Bei unseren 128 Wörtern geht die Rechnung ohnehin glatt auf, aber die zweistellige Zahl mit ihren 90 Möglichkeiten wäre sonst schief.
for (let i = 0; i < anzahl; i++) {
gezogen.push(woerter[zufallszahl(woerter.length)]);
}
let satz = gezogen.join(trenner);
Die Schleife zieht so oft ein Wort, wie eingestellt wurde, und legt es im Array gezogen ab. Wichtig: Es wird mit Zurücklegen gezogen — dasselbe Wort kann zweimal vorkommen. Das ist Absicht, denn nur dann hat jede Ziehung wirklich 128 gleichwahrscheinliche Ausgänge. join klebt das Array am Ende mit dem Trennzeichen zu einer Zeichenkette zusammen.
let bits = anzahl * Math.log2(woerter.length);
Die Stärke ergibt sich direkt aus der Anzahl der Ziehungen: Math.log2(128) ist genau 7, vier Wörter ergeben also 28 Bit. Beachtet, dass hier die Anzahl der Wörter zählt und nicht die der Zeichen — für einen Angreifer, der das Verfahren kennt, ist der Passsatz eine Folge aus vier Symbolen, nicht aus 24 Buchstaben.
Zum Anpassen: Die Wortliste dürft ihr austauschen, etwa gegen Fachbegriffe aus eurem Verein. Achtet nur darauf, dass alle Einträge verschieden sind — doppelte Wörter verzerren die Wahrscheinlichkeiten. Die Zeile mit Math.log2 rechnet automatisch mit der neuen Listenlänge weiter, ihr müsst also nichts nachziehen.
Script für die eigene Homepage
Kopiert euch den kompletten Code und fügt ihn an der Stelle eurer Seite ein, an der das Script erscheinen soll. Er läuft ohne weitere Dateien und ohne fremde Server.