2015-07-16 15 views
11

Chcę wygenerować kryptograficznie bezpieczne unikalne uuids za pomocą php.Kryptograficznie bezpieczny unikalny identyfikator

Funkcja uniqid() zapewnia unikalne, ale nie bezpieczne identyfikatory, a openssl_random_pseudo_bytes() zapewnia bezpieczne, ale nie unikalne identyfikatory. Czy połączenie dwóch (po kodzie) właściwego podejścia jest lepszym rozwiązaniem?

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

Odpowiedz

-1

Dlaczego nie mieszać wyjścia z openssl_random_pseudo_bytes? Można również Concat znacznik czasu i mieszania go potem

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

Korzystanie md5 tylko jako przykład. Możesz użyć dowolnego algorytmu skrótu.

+0

Co by to osiągnąć? – Cybergibbons

+1

MD5 nie jest bezpiecznym algorytmem mieszającym. – starbeamrainbowlabs

7

Chcę wygenerować kryptograficznie bezpieczne unikatowe uuids za pomocą php.

OK, to łatwo zrobić.

Funkcja uniqid() zapewnia unikalne, ale nie bezpieczne identyfikatory, a openssl_random_pseudo_bytes() zapewnia bezpieczne, ale nie unikalne identyfikatory.

Co powoduje, że numer cryptographically secure pseudorandom number nie jest unikalny?

/** 
* 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)) 
    ]); 
} 

Powyższy przykład jest zgodny z UUIDv4 specification i wykorzystuje random_bytes() funkcji PHP7'S.

dla PHP 5 projektów, można użyć random_compat do PolyFill random_bytes() z PHP 7.

+0

Dla osób korzystających z php, zobacz https://stackoverflow.com/a/18890309/3774582 na przykład openssl_random_pseudo_bytes(), aby utworzyć bezpieczny unikalny identyfikator kryptograficzny. – Goose

+1

@Goose Użyj random_compat, ** not ** openssl_random_pseudo_bytes: https://github.com/ramsey/uuid/issues/80 –

-1

Choć top odpowiedź jest praktycznie poprawne, to nie jest teoretycznie poprawne.

Twoje pytanie również nie ma idealnej odpowiedzi.

Bezpieczeństwo opiera się na bezstronnej, nieprzewidywalnej, prawdziwej losowości. Ale coś, co jest naprawdę przypadkowe, może się powtarzać, albo nie będzie przypadkowe. Milionowa kostka mogła wylądować na tej samej liczbie milion razy z rzędu, prawdopodobieństwo tego zdarzenia jest bardzo małe.

Siłą UUIDv4 jest to, że prawdopodobieństwo uzyskania tego samego identyfikatora dwukrotnie (kolizja) jest astronomicznie małe, "wybierz ten sam atom z galaktyki dwa razy" w rodzaju małego.

Każda próba dodania niepowtarzalności zmniejszy w rzeczywistości poziom bezpieczeństwa. Można dodać mikrosekundowy sygnaturę czasową lub wartość auto-inkrementującą oraz dokładność przestrzenną z dokładnością do milimetra, aby zagwarantować wyjątkowość. Ale dodajesz informacje o tym, gdzie i w jaki sposób iw jakiej kolejności utworzono identyfikator ...

Ponownie, ze względów praktycznych, można bezpiecznie używać UUIDv4 jako bezpiecznego i unikalnego identyfikatora.

Zdaj sobie również sprawę, że md5, sha1, uniqid itp. Nie są doskonałe same w sobie, a łączenie ich w losowy sposób niekoniecznie zmniejsza kolizje lub zwiększa bezpieczeństwo. Funkcje skrótu są w najlepszym razie tak unikalne jak to, z czym się mieszasz, i zazwyczaj zmniejszają wyjątkowość.

Odpowiedź zawsze dotyczy losowości i długości.

+0

Właściwie mówimy o kości większej niż kilka miliardów razy i prawdopodobieństwie twojego rzutu to samo, co x jest dokładnie "n^x". To astronomiczne, że potrzeba 6 610 lat mocy obliczeniowej, aby znaleźć kolizję Sha1. Ponadto, łączenie ich z pewnością zmniejsza liczbę kolizji o iloczyn prawdopodobieństw. – Bluebaron

Powiązane problemy