Sven Rautenberg: Und jetzt, warum das falsch ist:

Beitrag lesen

Moin!

Moin!

was sollte ich dann deiner Meinung nach nehmen, dass ich eine "sichere" und einmalige Zahl habe, die man nicht so einfach erraten kann?

Tja. Wie wäre es, wenn Du schon

$zufall = uniqid() . uniqid() . uniqid();

nimmst, auf das md5() drumrum einfach zu verzichten - statt die Rechenleistung kontraproduktiv zu "missnutzen"?

Reden wir von Zufallszahlen? Dann ist uniqid() so ziemlich das falscheste, was man nehmen kann, denn da gehen nur Parameter in die Bildung mit ein, die man kennen bzw, raten kann.

Siehe Handbuch: http://php.net/uniqid

Zitate:

Warning This function does not create random nor unpredictable strings. This function must not be used for security purposes. Use a cryptographically secure random function/generator and cryptographically secure hash functions to create unpredictable secure IDs.

Caution This function does not generate cryptographically secure tokens, in fact without being passed any additional parameters the return value is little different from microtime(). If you need to generate cryptographically secure tokens use openssl_random_pseudo_bytes().

Grundsätzlich kann man sagen, dass uniqid() mit dem Fortschritt der Zeit aufsteigende IDs erzeugt, weil die aktuelle Systemzeit in die Bildung der ID mit einfließt. Wie gut man Microtime erraten kann, kann man sich denken: Einfach auf die Uhr gucken verrät den größten Teil, unsicher sind allenfalls die Sekunden und Millisekunden.

Es hilft auch nichts, das Ergebnis von uniqid() in md5() reinzustecken, denn der Wertebereich von uniqid ist begrenzt: Es werden standardmäßig Strings von 13 Zeichen Länge aus dem Hexzahlenbereich 0-9A-F erzeugt. md5() ändert an diesem begrenzten Wertebereich nichts, d.h. es entstehen maximal soviele verschiedene MD5-Hashes, wie es 13-stellige Hexzahlen gibt - die restlichen mit MD5 erzeugbaren Werte werden nie produziert.

Kommen wir also zurück auf die Ausgangsfrage: Datenbank und Autoinkrement gefallen nicht, es soll etwas sein, was so eindeutig ist wie Autoinkrement, aber weniger einfach zu erraten.

Wenn man etwas nicht erraten soll, braucht man starken, kryptografischen Zufall. Und wenn etwas eindeutig sein soll, und man das sicherzustellen hat, braucht man eine Datenbank mit UNIQUE-Spalte, in die man den Zufallswert reinschreibt und dabei evtl. merkt, dass man den schon früher erzeugt hatte und einen neuen Wert ermitteln muß.

Wie man in PHP bestmöglich je nach Systemfähigkeiten Zufallsquellen anzapft, sieht man hier:

https://github.com/ircmaxell/password_compat/blob/6147131320e930186a37bc942ae067636302cf1c/lib/password.php#L102-L137

Das Schreiben des ermittelten Wertes in eine DB-Spalte mit UNIQUE-Index muss ich vermutlich nicht genauer ausführen.

Grüße Sven