Hallo,
sobald man die Startzahl kennt, kann man die Zahlen vorhersagen.
PHP:
<?php
srand(12345);
for($i=0;$i<10;$i++)
echo rand(0,100)."<br>";
?>
Dieser Script gibt dir immer die gleichen Zufallszahlen aus, denn der Startwert ist immer die gleiche (12345).
Wenn man jetzt den Startwert kennt, kann man also die "Zufallszahlen" voraussagen.
Kennt man nur die Zufallszahlen, dann kann es u.U. sein, dass man über die Zufallszahlen an den Startwert. Solche Algorithmen nennen sich dann: Kryptographisch unsicher.
Des weiteren wenn man folgenden Startwert bentutzt:
mt_srand((double)microtime()*1000000); (da seed = int ist)
Dann gibt es max. 1 Millionen mögliche Startwerte. Lässt man jetzt so ein zufälliges Passwort erstellen, dann gibt es max. 1 Mio. Passwörte, die man doch relativ schnell durchtesten kann, sogar über das Internet (bei 100 Passwörter/Sek dauert es ca. 2 Stunden).
Also zur Erstellung eines PW sehr ungeeignet, dieses Verfahren.
Die PHP rand() Funktion benutzt den in der jeweiligen libc enthaltenen Zufallsgenerator. Gerade in älteren libc-Versionen ist dieser aber oft langsam und die Qualität der erzeugten Pseudozufalls-Sequenzen ist unbefriedigend bis unbekannt.
PHP-Manual
Laut Bruce Schneier in "Angewandter Kryptographie", sind die enthaltenen Zufallsgeneratoren in Compilern/C-Libs meistens extrem schlecht und unsicher und lassen sich relativ leicht knacken, deswegen rät er ab, die fertige rand() Funktion von deinem C-Compiler zu verwenden.
Unter Windows lasse ich mit PHP z.B. ein Bild erzeugen, dabei werden mit rand() "zufällige" Punkte auf dem Bild eingezeichnet.
Allerdings sind diese Punkte gar nicht zufällig, sondern ergeben ein schönes Streifenmuster. Unter Linux sah dies anders aus. (Siehe Anhang PHP Code)
Dann gibt es noch die mt_rand() Funktion, die auf den "Mersenne Twister" zurückgreift.
Unlike Blum Blum Shub, the algorithm in its native form is not suitable for cryptography
Wikipedia
Also sind die Algorithmen an sich schonmal nicht kryptographisch sicher.
Dann kommt noch die falsche Handhabung
So dann gab es dort noch die "Netscape Story":
Ein reduzierter Schlüsselraum wurde Mitte 1995 bekannt im bekannten Browser Netscape.
Wenn man z.B. Kreditkartennummern chiffriert senden möchte, erzeugt das Programm einen 128 Bit langen Sitzungsschlüssel. Innerhalb der USA drufte nur effektiv 40 Bit des Schlüssels benutzt werden.
Selbst 2^40 ist eine ordentliche große Zahl, ca. 10^12 oder 1 Billionen (Anmerkung: Heutzutage in ca. 1 Tag geknackt) wäre ein damaliger PC rund 12 Tage beschäftig.
Doch der (Pseudo)Zufallsgenerator für den Sitzungsschlüssel von Netscape war wenigstens unter den UNIX-System Solaris und HP-UX nicht zufällig genug. Er wurde mit einer Größe initialisiert, die von der Systemzeit abhing (auf Mikrosekunden genau gemessen) sowie von den Identifikationsnummern des aktuellen und des Elternprozesses (den PID und PPID).
Daraus ergibt sicht eine Varianstionsbreite/Startwerte von 10^18 Möglichkeiten.
Wenn jedoch jmd. Zugang zu dem gleichen Rechter hat, dann kann er die PID und PPID des Anwenders sehr leicht bestimmen, und die Systemzeit wird er mindestens mit Minutengenauigkeit ermitteln können.
Es bleiben wenige zig Millionen Möglichkeiten übrig (10^7).
Um den Faktor 10^11 - also 100 Mrd. - hat sich hier die Variationsbreite verkleinert!
Und bei nur 1000 Versuchen pro Sekunde (Elderan: Heutige PC's schaffen 15 Mio Keys/Sek) wäre ein Rechner nach drei Stunden fertig!.
Doch die Praxis ist noch schöner: Oft genug kann man in einem Rechner die Zeit gar nicht auf die Mikrosekunde genau messen, sodern z.B. nur in 10ms-Intervallen.
Dann hat man noch einmal vier Größenordnungen gewonne, der Rechner arbeitet nur noch 10 Sekunden. Der volle Brute Force angriff auf den 40 Bit Key mit 1000 Versuche pro Sekunde hätte volle 30 Jahre gedauert.
....
Netscape behob den Fehler umgehened.
Quelle: Abenteuer Kryptologie ISBN: 3 -8273-1815-7
Anhang:
PHP:
<?php
//Code entweder mit code.php?method=rand oder mit
//code.php?method=mt_rand aufrufen
//Ergebnis hängt je von der rand Funktion eurer Lib ab.
mt_srand((double)microtime()*1000000);
srand((double)microtime()*1000000);
$image = imagecreate(1000,650) OR die("Fehler beim Erstellen des Bildes");
$farbe_body=imagecolorallocate($image,210,210,210);
if($_GET["method"] == "rand") $farbe_pixel = imagecolorallocate($image,255,0,0);
else $farbe_pixel = imagecolorallocate($image,0,0,255);
for($i = 0;$i<7000;$i++) {
if($_GET["method"] == "mt_rand") {
$x = mt_rand(0,1000);
$y = mt_rand(0,650);
} else {
$x = rand(0,1000);
$y = rand(0,650);
}
imagesetpixel($image, $x, $y, $farbe_pixel);
}
header("Content-Type: image/png");
imagepng($image);
?>