2015-07-16 13 views
11

Ich möchte kryptographisch sichere Unique UUIDs mit PHP generieren.Kryptographisch sichere eindeutige ID

uniqid() bietet eindeutige aber nicht sichere IDs und openssl_random_pseudo_bytes() bietet sichere, aber nicht eindeutige IDs. Ist die Kombination der beiden (folgender Code) ein geeigneter Ansatz oder gibt es eine bessere Lösung?

uniqid(bin2hex(openssl_random_pseudo_bytes(10)), true); 

Antwort

-1

Warum Hashing nicht die Ausgabe von openssl_random_pseudo_bytes? Sie könnten auch einen Zeitstempel verketten und es Hash danach

md5(bin2hex(openssl_random_pseudo_bytes(10)).strval(time())); 

md5 Mit nur als Beispiel. Sie können einen beliebigen Hash-Algorithmus verwenden.

+0

Was würde das erreichen? – Cybergibbons

+1

MD5 ist kein sicherer Hash-Algorithmus. – starbeamrainbowlabs

7

Ich möchte kryptographisch sichere Unique UUIDs mit PHP erzeugen.

Okay, das ist leicht gemacht.

uniqid() bietet eindeutige aber nicht sichere IDs und openssl_random_pseudo_bytes() bietet sichere, aber nicht eindeutige IDs.

Was lässt Sie denken, dass cryptographically secure pseudorandom number nicht einzigartig ist?

/** 
* Return a UUID (version 4) using random bytes 
* Note that version 4 follows the format: 
*  xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx 
* where y is one of: [8, 9, A, B] 
* 
* We use (random_bytes(1) & 0x0F) | 0x40 to force 
* the first character of hex value to always be 4 
* in the appropriate position. 
* 
* For 4: http://3v4l.org/q2JN9 
* For Y: http://3v4l.org/EsGSU 
* For the whole shebang: https://3v4l.org/LNgJb 
* 
* @ref https://stackoverflow.com/a/31460273/2224584 
* @ref https://paragonie.com/b/JvICXzh_jhLyt4y3 
* 
* @return string 
*/ 
function uuidv4() 
{ 
    return implode('-', [ 
     bin2hex(random_bytes(4)), 
     bin2hex(random_bytes(2)), 
     bin2hex(chr((ord(random_bytes(1)) & 0x0F) | 0x40)) . bin2hex(random_bytes(1)), 
     bin2hex(chr((ord(random_bytes(1)) & 0x3F) | 0x80)) . bin2hex(random_bytes(1)), 
     bin2hex(random_bytes(6)) 
    ]); 
} 

Das obige Beispiel entspricht die UUIDv4 specification und verwendet random_bytes() Funktion des PHP7.

Für PHP 5-Projekten können Sie random_compat verwenden random_bytes() von PHP 7.

+0

Für diejenigen, die PHP verwenden, siehe https://StackOverflow.com/a/18890309/3774582 für ein Beispiel für openssl_random_pseudo_bytes(), um eine kryptographisch sichere eindeutige ID zu erstellen. – Goose

+1

@Goose Verwenden Sie random_compat, ** nicht ** openssl_random_pseudo_bytes: https://github.com/ramsey/uuid/issues/80 –

-1

Selbst POLYfill obwohl die Top-Antwort praktisch korrekt ist, dann ist es theoretisch nicht korrekt.

Ihre Frage hat auch keine perfekte Antwort.

Sicherheit beruht auf unvoreingenommener, unvorhersehbarer, echter Zufälligkeit. Aber etwas, das wirklich zufällig ist, kann immer wiederholen, oder es wäre nicht zufällig. Ein millionenseitiger Würfel könnte millionenfach hintereinander auf der gleichen Zahl landen, die Wahrscheinlichkeit dafür ist nur sehr gering. Die Stärke von UUIDv4 ist, dass die Wahrscheinlichkeit, zweimal die gleiche ID zu bekommen (Kollision), astronomisch klein ist, das "selbe Atom aus einer Galaxie zweimal auswählen".

Jeder Versuch, die Eindeutigkeit hinzuzufügen, wird die Sicherheit verringern. Sie können einen Mikrosekundenzeitstempel oder einen automatisch inkrementierenden Wert und eine millimetergenaue räumliche Koordinate hinzufügen, um die Eindeutigkeit zu gewährleisten. Aber dann fügen Sie Informationen darüber hinzu, wo und wie und in welcher Reihenfolge die ID erstellt wurde ...

Auch in diesem Fall ist es sicher, UUIDv4 als sichere und eindeutige Kennung zu verwenden. realisieren

auch, dass md5, sha1, uniqid usw. selbst nicht perfekt sind, und sie in zufälliger Weise kombiniert verringert nicht notwendigerweise Kollision oder die Sicherheit erhöhen. Hashing-Funktionen sind bestenfalls so einzigartig wie das, was Sie hashen, und normalerweise verringern sie die Eindeutigkeit.

Die Antwort liegt immer in Zufälligkeit plus Länge.

+0

Wir sprechen tatsächlich über größer als ein mehrere Milliarden Seiten sterben und die Wahrscheinlichkeit Ihres Rollens Das gleiche Ding x-mal ist genau "n^x". Es ist so astronomisch, dass es 6.610 Jahre Rechenleistung brauchte, um eine Kollision zu finden. Auch die Kombination von Kollisionen reduziert das Produkt der Wahrscheinlichkeiten. – Bluebaron