Da ich derzeit an einer kompletten Neuentwicklung für eine Community-Software sitze, stehe ich unter anderem vor dem Problem, dem Benutzer neue Passwörter vorzuschlagen bzw. auch automatisch neue Passwörter generieren zu lassen. Diese Passwörter sollten natürlich sicher sein. Doch was ist dazu zu beachten?
Generell sollte man natürlich darauf achten, dass das Passwort nicht mit Hilfe eines Wörterbuchs herausfindbar ist. Durch solche Passwörter ist es Hackern ein Leichtes, schnell an das nötige Passwort zu kommen. Beispiele für solche sehr schlechten Passwörter sind “MeinNameIstHans” oder “SicheresPasswort1″.
Sollte ein Wörterbuch nicht mehr beim Hacken ausreichen, wird ein BruteForce-Algorithmus angewendet, der praktisch mit roher Gewalt alle möglichen Buchstaben und Wortkombinationen ausprobiert, um ans Ziel zu kommen. Dass diese Methode nicht abwegig ist, zeigt der Artikel Password Recovery Speed: so kann ein 9-stelliges Passwort, das nur aus Zahlen besteht, auf einem Pentium-100 in 28 Stunden geknackt werden. Auf heutigen Rechnern dürfte sich dann nicht mal das Anschalten der Kaffeemaschine lohnen. Erst bei der Verwendung des vollen Alphabets (groß und klein) sowie von Zahlen und Sonderzeichen ergibt sich ein Passwort, das ab einer gewissen Mindestlänge auch auf leistungsstarken Rechnern aufwendig zu knacken ist und damit relativ sicher sein sollte.
Das Problem an diesen Passwörtern ist aber: wer kann sie sich merken? Es gibt sicherlich Software, welche die Passwörter für mich speichert (darunter zähle ich jetzt auch einfach mal die bekannten Haftnotizen, die viele Bildschirme veredeln). Dies macht die Sache aber nicht sicherer.
Eine Lösung stellen mnemonische Verfahren dar (siehe Mnemonik), die versuchen, Passwörter derart zu generieren, dass sie aussprechbar sind. Und ein solches versuchte ich nun zu implementieren. Da ich den Code für recht hilfreich finde, veröffentliche ich ihn hier:
function createRandomPassword() {
$vokale = "aeiouy";
$konsonanten = "bcdfghjklmnprstvwxz";
$special = '!#$%&*+-/< =>?@^_~';
$password = "";
//zufällige Länge zwischen 4 und 10 Zeichen festlegen
$sizeCharacter = mt_rand(3,7);
for($i = 1; $i <= $sizeCharacter; $i++) {
$passwort .= substr($konsonanten,
mt_rand(0, strlen($konsonanten)-1), 1);
$passwort .= substr($vokale, mt_rand(0, strlen($vokale)-1), 1);
}
//zufälliges Sonderzeichen einfügen
$passwort .= substr($special, mt_rand(0, strlen($special)-1), 1);
//Zufällige Anzahl an Zahlen einfügen
$sizeNumbers = mt_rand(1,3);
for($i = 1; $i <= $sizeNumbers; $i++) {
$passwort .= mt_rand(0,9);
}
return $passwort;
}
Diese Funktion erzeugt Passwörter mit mindestens 6 Zeichen, maximal 14 Zeichen. Zur einfachen Aussprache wechselt sie zufällig Vokale (inkl. y!) und Konsonanten aus. Erzeugte Passwörter sehen z.B. so aus:
- givubyru@956
- wasurityzujasy!39
- jumexa@13
- hutydorufanuwy#44
- zidacy%4
- hafiby!35
- fadujudimy%52
- wykigy%263
- feweda@202
Sicher nicht jedes perfekt, aber meiner Meinung nach schon recht gut. Anderer Meinung? Verbesserungsvorschläge?
[Update]
Mit den Vorschlägen von Martin (siehe Kommentare) hab ich die Funktion jetzt etwas angepasst. Sie kann jetzt auch Großbuchstaben (hatte ich in der ersten Funktion komplett vergessen). Dabei wird berücksichtigt, dass zuviele Großbuchstaben schwer zu merken sind und dass dies noch einfacher fällt, wenn die Großbuchstaben nur Konsonanten sind.
function st_createRandomPassword($minpairs = 2, $maxpairs = 5,
$minnumbers = 1, $maxnumbers = 3){
$vowels = "aeiou";
$consonants = "bcdfghjklmnprstvwxz";
$specialchars = '!#$%&*+-/< =>?@^_~';
$password = "";
$pairs = mt_rand($minpairs, $maxpairs);
$lenv = strlen($vowels)-1;
$lenc = strlen($consonants)-1;
$usedBig = false; //Großbuchstabe bereits eingefügt wurde
for($i = 1; $i < = $pairs; $i++) {
$password .= $vowels[mt_rand(0, $lenv)];
if (mt_rand(0,1)==0 && !$usedBig) {
$password .= strtoupper($consonants[mt_rand(0, $lenc)]);
if (mt_rand(0,1)==0) $usedBig=true;
} else {
$password .= $consonants[mt_rand(0, $lenc)];
}
}
//zufälliges Sonderzeichen einfügen
$password .= $specialchars[mt_rand(0, strlen($specialchars)-1)];
//Zufällige Anzahl an Zahlen einfügen
$sizeNumbers = mt_rand($minnumbers, $maxnumbers);
for($i = 1; $i <= $sizeNumbers; $i++) {
$password .= mt_rand(0,9);
}
return $password;
}
[Update 2]
In aktuellen PHP-Versionen scheint die eckige-Klammmer-Variante nicht mehr zu gehen. Deshalb hier die korrigierte Version:
function st_createRandomPassword($minpairs = 2, $maxpairs = 5,
$minnumbers = 1, $maxnumbers = 3){
$vowels = "aeiou";
$consonants = "bcdfghjklmnprstvwxz";
$specialchars = '!#$%&*+-/< =>?@^_~';
$password = "";
$pairs = mt_rand($minpairs, $maxpairs);
$lenv = strlen($vowels)-1;
$lenc = strlen($consonants)-1;
$usedBig = false; //Großbuchstabe bereits eingefügt wurde
for($i = 1; $i < = $pairs; $i++) {
$password .= $vowels{mt_rand(0, $lenv)};
if (mt_rand(0,1)==0 && !$usedBig) {
$password .= strtoupper($consonants{mt_rand(0, $lenc)});
if (mt_rand(0,1)==0) $usedBig=true;
} else {
$password .= $consonants{mt_rand(0, $lenc)};
}
}
//zufälliges Sonderzeichen einfügen
$password .= $specialchars{mt_rand(0, strlen($specialchars)-1)};
//Zufällige Anzahl an Zahlen einfügen
$sizeNumbers = mt_rand($minnumbers, $maxnumbers);
for($i = 1; $i <= $sizeNumbers; $i++) {
$password .= mt_rand(0,9);
}
return $password;
}
Erzeugte Passwörter:
- oWatus^885
- aToDosop@03
- iWiwatur+48
- eNiguTad!7
- adalowiLuv-350
- ajoW=3
- uSapen%61
- ozaDokaLes=417
- iNesebav%456
- oKaPogoz>5