Um ein 32-stelliges Token für den Zugriff auf unsere API zu generieren, verwenden wir derzeit:
$token = md5(uniqid(mt_rand(), true));
Ich habe gelesen, dass diese Methode nicht kryptografisch sicher ist, da sie auf der Systemuhr basiert, und das openssl_random_pseudo_bytes
wäre eine bessere Lösung, da es schwieriger vorherzusagen wäre.
Wenn dies der Fall ist, wie würde der entsprechende Code aussehen?
Ich nehme so etwas an, aber ich weiß nicht, ob das richtig ist ...
$token = md5(openssl_random_pseudo_bytes(32));
Auch welche Länge macht Sinn, dass ich an die Funktion übergeben soll?
md5()
generiert eine 32-stellige Zeichenfolge, enthält jedoch nur Daten im Wert von 128 Bit.openssl_random_pseudo_bytes()
Gibt echte Binärdaten zurück, hat also 32 * 8 = 256 Bit Zufälligkeit. Indem Sie Ihre 32-Byte-Zufallszeichenfolge durch md5 stopfen, reduzieren Sie effektiv ihre Einzigartigkeit um einen massiven Betrag.$token = bin2hex(openssl_random_pseudo_bytes(16));
ausreichend oder brauche ich eine Schleife von 16 Iterationen, die 1 als Länge übergeben und hexadezimal an eine Zeichenfolge anhängen?Random::alphanumericString($length)
die ungefähr 2 Milliarden Mal so viel „Entropie“ in diese 16 Zeichen passt.Antworten:
Hier ist die richtige Lösung:
$token = bin2hex(openssl_random_pseudo_bytes(16)); # or in php7 $token = bin2hex(random_bytes(16));
quelle
bin2hex(random_bytes($length/2))
Sie auch, weil Sie 2 Hex-Zeichen für jedes Byte haben können, so dass die Anzahl der Zeichen$length
ohne es immer doppelt ist$length
Anzahl von Zeichen erzeugt (anstatt sich um die Bytegröße zu kümmern), möchten Sie übergebenrandom_bytes($length/2)
.Wenn Sie openssl_random_pseudo_bytes verwenden möchten, verwenden Sie am besten die CrytoLib-Implementierung. Auf diese Weise können Sie alle alphanumerischen Zeichen generieren. Wenn Sie bin2hex um openssl_random_pseudo_bytes kleben, erhalten Sie nur AF (Großbuchstaben) und Zahlen.
Ersetzen Sie den Pfad / zu / durch den Speicherort der Datei cryptolib.php (Sie finden ihn auf GitHub unter: https://github.com/IcyApril/CryptoLib ).
<?php require_once('path/to/cryptolib.php'); $token = IcyApril\CryptoLib::randomString(16); ?>
Die vollständige CryptoLib-Dokumentation finden Sie unter: https://cryptolib.ju.je/ . Es behandelt viele andere zufällige Methoden, die kaskadierende Verschlüsselung sowie die Generierung und Validierung von Hashs. aber es ist da, wenn Sie es brauchen.
quelle
openssl_random_pseudo_bytes(16)
Jedes Byte kann einen beliebigen Wert (0-255) haben, währendrandomString(16)
jedes Byte nur az Az 0-9 haben kann, was 62 Kombinationen pro Byte entspricht. Yup randomString ist pro Zeichenfolgenlänge besser , da bin2hex eine ineffiziente Codierung ist (50%). Besserbase64_encode(openssl_random_pseudo_bytes(16))
für eine kürzere Zeichenfolge und eine genau bekannte Anzahl von Sicherheitsbytes (16 in diesem Fall, aber nach Bedarf ändern)+
,/
und=
Zeichen, also , wenn Sie versuchen , ein benutzerfreundliches Token zu generieren (zB einen API - Schlüssel) ist es nicht ideal ist.Wenn Sie einen kryptografisch sicheren Zufallszahlengenerator haben, müssen Sie dessen Ausgabe nicht hashen. Tatsächlich willst du nicht. Benutz einfach
$token = openssl_random_pseudo_bytes($BYTES,true)
Wobei $ BYTES wie viele Datenbytes Sie möchten. MD5 hat einen 128-Bit-Hash, also reichen 16 Bytes.
Nebenbei bemerkt, keine der Funktionen, die Sie in Ihrem Originalcode aufrufen, ist kryptografisch sicher. Die meisten sind so schädlich, dass die Verwendung nur einer Funktion unsicher wäre, selbst wenn sie mit sicheren anderen Funktionen kombiniert wird. MD5 weist Sicherheitsprobleme auf (obwohl diese für diese Anwendung möglicherweise nicht relevant sind). Uniqid generiert nicht nur standardmäßig keine kryptografisch zufälligen Bytes (da es die Systemuhr verwendet), sondern die hinzugefügte Entropie, die Sie übergeben, wird mithilfe eines linearen kongruenten Generators kombiniert, der nicht kryptografisch sicher ist. In der Tat bedeutet dies wahrscheinlich, dass Sie alle Ihre API-Schlüssel erraten können, wenn Sie Zugriff auf einige von ihnen haben, selbst wenn sie keine Ahnung vom Wert Ihrer Serveruhr hatten. Schließlich ist mt_rand (), was Sie als zusätzliche Entropie verwenden, auch kein sicherer Zufallszahlengenerator.
quelle
Zuverlässige Passwörter können Sie nur aus machen ascii Zeichen a-zA-Z und die Zahlen 0-9 . Um dies zu erreichen, verwenden Sie am besten nur kryptografisch sichere Methoden wie random_int () oder random_bytes () aus PHP7. Restfunktionen als base64_encode () Sie können nur als Unterstützungsfunktionen verwenden, um die Zuverlässigkeit der Zeichenfolge zu erhöhen und sie in ASCII- Zeichen zu ändern .
mt_rand () ist nicht sicher und sehr alt. Aus einer beliebigen Zeichenfolge Sie müssen random_int () verwenden. Von der Binärzeichenfolge Sie sollten base64_encode () verwenden , um die Binärzeichenfolge zuverlässig zu machen, oder bin2hex, aber dann werden Sie das Byte nur auf 16 Positionen (Werte) schneiden. Siehe meine Implementierung dieser Funktionen. Es werden alle Sprachen verwendet.
quelle