2010-04-07 4 views
5

Ho creato un salt usando; MD5 (rand (0,10000000)); (c'è probabilmente un modo migliore?)Campo di testo unico in MySQL e php

Non sembra possibile rendere un campo di testo univoco in MYSQL. Quindi, come posso controllare se il sale è già stato utilizzato per un utente precedente?

Oppure devo generare il sale in base alla data/ora corrente? come è impossibile per 2 utenti registrarsi esattamente allo stesso tempo corretto?

+1

è possibile aggiungere un vincolo univoco su un campo varchar - si potrebbe usare che per verificare la presenza di sali di duplicati. – thetaiko

risposta

1

Per un sale, l'unicità è più importante della lunghezza e della prevedibilità. Assumi che l'attaccante ha il sale.

Un identificatore univoco universale (UUID) sarebbe meglio, e ci sono esempi che generano uuid nella pagina doc per la funzione php uniqueid(). Un UUID ha il vantaggio su una stringa casuale in quanto è leggibile e di lunghezza fissa, pertanto è possibile memorizzarlo in un campo varchar e utilizzare un indice univoco per assicurarsi che non ci siano mai duplicati.

L'hashing dell'ora con MD5 è un metodo comune per generare valori univoci perché ha una lunghezza fissa ed è leggibile dall'uomo. Tuttavia, ha più senso solo generare una stringa casuale di lunghezza fissa e codificarla in esadecimale. Gli hash non sono progettati per l'unicità così come sono progettati per non essere reversibili. L'uso di una funzione di hashing garantisce le collisioni, anche se ci saranno meno collisioni con SHA1 che MD5.

La lunghezza del sale è davvero solo un fattore perché più lungo è il sale, più è probabile che sia universalmente unico.

+0

dovrebbe essere una strana coincidenza 2 utenti che succedono hanno lo stesso salt decidono di avere la stessa password, quindi –

+0

@Jonathan, se ci sono doppi duplicati con differenti password digests, attaccherò quegli account prima dato che mi dà una possibilità migliore nel trovare una collisione di successo. Due account con lo stesso sale e password darebbero l'attacker due al prezzo di uno, ma l'attaccante non ha alcuna interruzione. –

0

md5() è un algoritmo danneggiato e non dovrebbe mai essere toccato.

rand() è leggermente rotto perché è basato sull'orologio di sistema.

Un metodo migliore è:

function generateRandomKey() 
{ 
    return base_convert(uniqid(mt_rand(), true), 16, 36); 
} 

Edit: Se c'è un modo migliore o mi sbaglio, per favore mi mostrano il vostro modo di farlo. Sono sinceramente interessato e vorrei sapere se sono insicuro.

+1

Per un'altra vista più ampiamente accettata, vedi http://stackoverflow.com/questions/2329609/is-it-safe-to-store-passwords-hashed-with-md5cryptoserviceprovider-in-c – dkretz

+0

@ledorifier, il link che hai postato è sulle password di hashing, non sulla generazione di sali casuali. –

+1

E http://stackoverflow.com/questions/157998/whats-the-difference-between-sha-and-md5-in-php. Mi riferivo a "... mai essere intenerito". – dkretz

0

Generare il sale con SHA1 utilizzando id utente e datetime.

1

Gli indici di MySQL sono limitati per lunghezza nei campi di testo, non vanno automaticamente a tutto campo come nei campi char/varchar, quindi non esiste un modo pratico per utilizzare una chiave "univoca" sui campi di testo.

Ma se siete memorizzare hash generati da MySQL, quindi non è necessario il testo - i risultati sono dispone di solo testo, quindi basta utilizzare un campo di lunghezza fissa char:

mysql> select length(md5('a')), length(sha1('a')); 
+------------------+-------------------+ 
| length(md5('a')) | length(sha1('a')) | 
+------------------+-------------------+ 
|    32 |    40 | 
+------------------+-------------------+ 

e poi È possibile applicare un vincolo univoco a quel campo.

0

Generalmente non si generano stringhe di sale. Quindi, quando li generi per la prima volta, dovresti fare un buon lavoro. Le stringhe più lunghe e più casuali sono migliori.

function generateSalt($length = null) 
{ 
    if (!is_int($length) || ($length < 1)) $length = 250; 
    do { 
    $salt[] = chr(mt_rand(0, 255)); 
    } while (--$length); 
    return implode('', $salt); 
} 

query di aggiornamento per la nuova password

update user set salt = :salt, password = sha1(concat(:password, :salt)) where id = :id limit 1; 

è possibile verificare se la password è corretta e ottenere i dati degli utenti, allo stesso tempo.

select * from user where id = :id and password = sha1(concat(:password, salt)) limit 1;