md5 (uniqid) ist sinnvoll für zufällige eindeutige Token?

Lesezeit: 7 Minuten

Benutzer-Avatar
Ausnahme z

Ich möchte einen Token-Generator erstellen, der Token generiert, die vom Benutzer nicht erraten werden können und die dennoch eindeutig sind (zur Verwendung für das Zurücksetzen von Passwörtern und Bestätigungscodes).

Ich sehe diesen Code oft; macht das Sinn?

md5(uniqid(rand(), true));

Laut a Kommentar uniqid($prefix, $moreEntopy = true) Erträge

erste 8 Hex-Zeichen = Unixtime, letzte 5 Hex-Zeichen = Mikrosekunden.

Ich weiß nicht, wie die $prefix-Parameter behandelt wird..

Wenn Sie also das $moreEntopy-Flag nicht auf true setzen, erhalten Sie ein vorhersehbares Ergebnis.


FRAGE: Aber wenn wir verwenden uniqid mit $moreEntopy, was bringt uns das Hashing mit md5? Ist es besser als:

md5(mt_rand())

edit1: Ich werde dieses Token in einer Datenbankspalte mit einem eindeutigen Index speichern, damit ich Spalten erkennen kann. Könnte interessant sein/

Benutzer-Avatar
Turm

rand() ist ein Sicherheitsrisiko und sollte niemals zum Generieren eines Sicherheitstokens verwendet werden: rand() vs. mt_rand() (Schauen Sie sich die “statischen” Bilder an). Aber keine dieser Methoden zur Generierung von Zufallszahlen ist kryptografisch sicher. Um sichere Secrets zu generieren, muss eine Anwendung auf a zugreifen CSPRNG bereitgestellt von der Plattform, dem Betriebssystem oder dem Hardwaremodul.

In einer Webanwendung ist eine gute Quelle für sichere Geheimnisse der nicht blockierende Zugriff auf einen Entropiepool wie z /dev/urandom. Ab PHP 5.3 können PHP-Anwendungen verwenden openssl_random_pseudo_bytes()und die Openssl-Bibliothek wählt die beste Entropiequelle basierend auf Ihrem Betriebssystem aus, unter Linux bedeutet dies, dass die Anwendung verwendet /dev/urandom. Dieser Codeausschnitt von Scott ist ziemlich gut:

function crypto_rand_secure($min, $max) {
        $range = $max - $min;
        if ($range < 0) return $min; // not so random...
        $log = log($range, 2);
        $bytes = (int) ($log / 8) + 1; // length in bytes
        $bits = (int) $log + 1; // length in bits
        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
            $rnd = $rnd & $filter; // discard irrelevant bits
        } while ($rnd >= $range);
        return $min + $rnd;
}

function getToken($length=32){
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    for($i=0;$i<$length;$i++){
        $token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))];
    }
    return $token;
}

  • md5() in this case is being used to obscure the time that it was created which is a legitimate use Das klingt nach der Antwort.

    – Ausnahme z

    7. April 2010 um 23:10 Uhr

  • Ich habe einen Serverprozess, der Formulardaten annehmen und als uniquetoken.xml speichern muss. Ich habe bereits das Formular bereit, um die XML-Datei zu erstellen. Bisher benenne ich sie mit jeder mmddyy.xml. Wie könnte ich es durch md5(uniqid(mt_rand(), true)) ersetzen; ?

    – marciokoko

    6. Januar 2012 um 15:44 Uhr

  • Das ist unsicher. Siehe Scotts Antwort.

    – ChocoDeveloper

    12. August 2013 um 14:15 Uhr

  • @ChocoDeveloper “/dev/urandom ist bei weitem die beste Entropiequelle für eine Webanwendung.”

    – Turm

    12. August 2013 um 16:17 Uhr

  • Ich spreche von dem Code-Snippet, das Sie bereitgestellt und als “für die meisten Sicherheitszwecke ist dies ein gutes Token” gekennzeichnet haben, das von Noobs verwendet werden kann. Außerdem ist /dev/urandom auch nicht “die beste Entropiequelle”, da es nicht blockiert. Es gibt einen Grund dafür openssl_random_pseudo_bytes() existiert.

    – ChocoDeveloper

    12. August 2013 um 16:27 Uhr


Benutzer-Avatar
Scott

Dies ist eine Kopie einer anderen Frage, die ich gefunden habe und die einige Monate vor dieser gestellt wurde. Hier ist ein Link zu der Frage und meiner Antwort: https://stackoverflow.com/a/13733588/1698153.

Ich bin mit der akzeptierten Antwort nicht einverstanden. Laut PHPs eigener Website "[uniqid] 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()."

Ich glaube nicht, dass die Antwort klarer sein könnte, uniqid ist nicht sicher.

  • upvoted, also sollten die Leute wirklich den Link anstelle der akzeptierten Antwort auschecken.

    – Perle

    9. September 2013 um 2:10 Uhr

  • Scott, diese ältere Frage war mir nicht bewusst, sry. ich vermute openssl_random_pseudo_bytes() (PHP 5 >= php 5.3) war zum Zeitpunkt der Anfrage nicht immer verfügbar. Sie haben Recht, die akzeptierte Antwort wurde geändert und bezieht sich auf Ihre Antwort in diesem Moment, damit andere Personen nicht in die Irre geführt werden.

    – Ausnahme z

    26. April 2014 um 11:34 Uhr

Benutzer-Avatar
Jarek Jakubowski

Ich weiß, die Frage ist alt, aber sie taucht in Google auf, also…

Wie andere sagten, rand(), mt_rand() oder uniqid() garantiert Ihnen keine Einzigartigkeit … nicht einmal openssl_random_pseudo_bytes() sollte nicht verwendet werden, da es verwendet veraltete Funktionen von OpenSSL.

Was Sie verwenden sollten, um zufälligen Hash (wie md5) zu generieren, ist random_bytes() (eingeführt in PHP7). Um einen Hash mit der gleichen Länge wie MD5 zu generieren:

bin2hex(random_bytes(16));

Wenn Sie PHP 5.x verwenden, können Sie diese Funktion durch Einschließen erhalten random_compat-Bibliothek.

  • Gültige Antwort! Ihr Anliegen bzgl openssl_random_pseudo_bytes() scheint behoben worden zu sein bugs.php.net/bug.php?id=70014.

    – Ausnahme z

    8. Februar 2017 um 10:08 Uhr

Definiere “einzigartig”. Wenn Sie meinen, dass zwei Token nicht denselben Wert haben können, reicht Hashing nicht aus – es sollte mit einem Eindeutigkeitstest unterlegt werden. Die Tatsache, dass Sie den Hash-Algorithmus mit eindeutigen Eingaben versorgen, garantiert keine eindeutigen Ausgaben.

Um Ihre Frage zu beantworten, das Problem ist, dass Sie keinen Generator haben können, der garantiert zufällig und einzigartig ist, da er selbst zufällig ist, dh md5(mt_rand()) kann zu Duplikaten führen. Was Sie wollen, sind “zufällig erscheinende” eindeutige Werte. uniqid gibt die eindeutige ID an, rand() hängt eine Zufallszahl an, die es noch schwerer zu erraten macht, md5 maskiert das Ergebnis, um es noch schwerer zu erraten. Nichts ist unvorhersehbar. Wir müssen es nur so schwer machen, dass sie es nicht einmal versuchen wollen.

  • Sie sagen “md5 maskiert das Ergebnis, um es noch schwerer zu erraten”. uniqueid erzeugt also ein etwas zufälliges Ergebnis, das einzigartig ist. Was genau meinst du mit maskieren? Wenn ich diesem Gedanken folgen würde md5(md5(uniqid(rand(), true) würde noch mehr Maskierung bedeuten, aber es ist schlimmer, oder?

    – Ausnahme z

    7. April 2010 um 17:10 Uhr


  • @Ausnahme e, ein doppelter md5()-Hash verbessert die Sicherheit dieses Systems nicht.

    – Turm

    7. April 2010 um 19:42 Uhr

Benutzer-Avatar
Herr47

Ich bin vor ein paar Jahren auf eine interessante Idee gestoßen.
Speichern von zwei Hash-Werten in der Datenbank, einer mit md5($a) und der andere mit sha($a). Überprüfen Sie dann, ob beide Werte korrekt sind. Der Punkt ist, wenn der Angreifer Ihr md5() gebrochen hat, kann er in naher Zukunft nicht Ihr md5 UND sha brechen.
Das Problem ist: Wie kann dieses Konzept mit der für Ihr Problem erforderlichen Token-Generierung verwendet werden?

  • Sie sagen “md5 maskiert das Ergebnis, um es noch schwerer zu erraten”. uniqueid erzeugt also ein etwas zufälliges Ergebnis, das einzigartig ist. Was genau meinst du mit maskieren? Wenn ich diesem Gedanken folgen würde md5(md5(uniqid(rand(), true) würde noch mehr Maskierung bedeuten, aber es ist schlimmer, oder?

    – Ausnahme z

    7. April 2010 um 17:10 Uhr


  • @Ausnahme e, ein doppelter md5()-Hash verbessert die Sicherheit dieses Systems nicht.

    – Turm

    7. April 2010 um 19:42 Uhr

Benutzer-Avatar
Lucian Minea

Erstens besteht der Umfang dieser Art von Verfahren darin, einen Schlüssel/Hash/Code zu erstellen, der für eine bestimmte Datenbank eindeutig ist. Es ist unmöglich, zu einem bestimmten Zeitpunkt etwas Einzigartiges für die ganze Welt zu schaffen. Davon abgesehen sollten Sie eine einfache, sichtbare Zeichenfolge erstellen, ein benutzerdefiniertes Alphabet verwenden und den erstellten Code mit Ihrer Datenbank (Tabelle) vergleichen. Wenn diese Zeichenfolge eindeutig ist, wenden Sie a an md5() dazu und das kann von niemandem und keinem Skript erraten werden. Ich weiß, wenn Sie tief in die Theorie der kryptografischen Generierung eintauchen, finden Sie viele Erklärungen zu dieser Art der Codegenerierung, aber wenn Sie sie in die Praxis umsetzen, ist es wirklich nicht so kompliziert.

Hier ist der Code, den ich verwende, um einen einfachen 10-stelligen eindeutigen Code zu generieren.

$alphabet = "aA1!bB2@cC3#dD5%eE6^fF7&gG8*hH9(iI0)jJ4-kK=+lL[mM]nN{oO}pP\qQ/rR,sS.tT?uUvV>xX~yY|zZ`wW$";
$code="";
$alplhaLenght = strlen($alphabet )-1;
for ($i = 1; $i <= 10; $i++) {
    $n = rand(1, $alplhaLenght );
    $code .= $alphabet [$n];
}

Und hier sind einige generierte Codes, obwohl Sie es selbst ausführen können, um zu sehen, wie es funktioniert:

SpQ0T0tyO%
Uwn[MU][.
D|[ROt+Cd@
O6I|w38TRe

Of course, there can be a lot of “improvements” that can be applied to it, to make it more “complicated”, but if you apply a md5() to this, it’ll become, let’s say “unguessable” . 🙂

1201370cookie-checkmd5 (uniqid) ist sinnvoll für zufällige eindeutige Token?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy