2010-07-17 11 views
10

Come la maggior parte degli utenti, sto semplicemente cercando di trovare un modo sicuro per archiviare le password. Quello che non ho trovato qui (o forse è la mia mancanza di comprensione) è come recuperare un hash salato nel mio database e separare il sale dalla password hash, in particolare con sali unici per ogni password mantenendo la password di sale + in una singola colonna.Salare i miei hash con PHP e MySQL

Sto trovando tutti questi modi interessanti per crittografare le password (SHA-256, ma MySQL supporta solo SHA/1 e MD5?) E altre cose dal manuale PHP, ma non sono sicuro di come memorizzare e recuperare le password.

Quindi, finora questo è tutto quello che comprendo:

SHA('$salt'.'$password') // My query sends the password and salt 
         // (Should the $salt be a hash itself?) 

Dopo di che mi sono perso con sali.

Recuperare la password senza sale è facile, ma il sale mi confonde. Dove posso ottenere nuovamente il valore da $ salt, specialmente se è unico e sicuro? Li nascondo in un altro database? Costante (sembra pericoloso)?

MODIFICA: La variabile chiave in HMAC dovrebbe essere salata o si tratta di qualcos'altro?

+0

FWIW, MySQL 5.5 integrato con supporto SSL include un 'SHA2 () 'funzione che fornisce gli algoritmi hash SHA224, SHA256, SHA384 e SHA512. Se stai usando una versione precedente di MySQL, usa la funzione 'hash()' in PHP. –

+0

Grazie ancora, Bill, questa è la seconda volta che hai aiutato! Sto usando 5.1 perché è venuto con WAMP (wampserver.com). Ho dovuto disinstallare il mio vecchio MySQL per installare questo. Sfortunatamente, non sono sicuro di come aggiornarlo ... Proverò a utilizzare PHP per la mia crittografia. – Tarik

risposta

5

Prima di tutto, DBMS (MySQL) non deve avere alcun supporto per hash crittografici. Puoi fare tutto ciò dal lato PHP, ed è anche quello che dovresti fare.

Se si desidera memorizzare sale e hash nella stessa colonna, è necessario concatenarli.

// the plaintext password 
$password = (string) $_GET['password']; 

// you'll want better RNG in reality 
// make sure number is 4 chars long 
$salt = str_pad((string) rand(1, 1000), 4, '0', STR_PAD_LEFT); 

// you may want to use more measures here too 
// concatenate hash with salt 
$user_password = sha512($password . $salt) . $salt; 

Ora, se si desidera verificare una password che fate:

// the plaintext password 
$password = (string) $_GET['password']; 

// the hash from the db 
$user_password = $row['user_password']; 

// extract the salt 
// just cut off the last 4 chars 
$salt = substr($user_password, -4); 
$hash = substr($user_password, 0, -4); 

// verify 
if (sha512($password . $salt) == $hash) { 
    echo 'match'; 
} 

Si potrebbe voler dare un'occhiata a phpass, che utilizza anche questa tecnica. È una soluzione di hashing PHP che utilizza la salatura tra alcune altre cose.

Si dovrebbe assolutamente dare un'occhiata alla risposta alla domanda WolfOdrade collegata a.

+0

Grazie! Un sacco di nuove funzioni, ma riesco a capire da solo il nitty grintoso. Questo e 'esattamente quello che stavo cercando. Non ho mai saputo della funzione di stringa di sottrazione, che aiuta. È possibile sottrarre dalla parte anteriore di una stringa il diverso posizionamento del sale? Grazie ancora! – Tarik

+0

Certo, il substr può gestire entrambi. Se hai un carattere di 4 caratteri in primo piano, dovresti fare: '$ salt = substr ($ user_password, 0, 4); $ hash = substr ($ user_password, 4); ' – igorw

+0

Grazie. Ho provato l'hash_hmac, ma ho problemi a confrontare la password di accesso con la password del database. Il sale in hash_hmac è generato casualmente, quindi come posso sottrarlo? Ho anche notato la stessa cosa nel tuo esempio. sha512 ($ password. $ salt) hashing la password e un salt unico. Come potrei ottenere quel salt unico per hash la password inserita con il passaggio del database? Scusa per il sovraccarico di domande, sono a pochi centimetri da questo! – Tarik

3

Questo sembra coperto in modo approfondito in un precedente post: Secure hash and salt for PHP passwords

+0

Ho letto la risposta migliore per questo prima di fare questa domanda e non ha risposto alla mia domanda. Fornisce un buon modo per memorizzare una password in modo sicuro, ma non è esattamente quello che sto cercando. – Tarik

0

Personalmente raccomando di fare in modo che MySQL faccia ciò con le sue funzioni incorporate.

Il modo in cui lo faccio è creare una funzione nel mio file di configurazione del database che restituisce una stringa di chiavi. Il file di configurazione deve trovarsi al di fuori della root del sito in modo che il server Web possa accedere al file ma non ad altri. così per esempio:

function enc_key(){ 
    return "aXfDs0DgssATa023GSEpxV"; 
} 

Poi nello script utilizzarlo con la query SQL e funzioni AES_ENCRYPT e AES_DECRYPT in MySQL come questo:

require_once('dbconf.inc.php'); 

$key = enc_key(); 

//When creating a new user 
$sql = "INSERT INTO users (username, password) VALUES ('bob', AES_ENCRYPT('{$key}', {$password}))"; 

//When retrieving users password 
$sql = "SELECT AES_DECRYPT('{$key}', password) AS password FROM users WHERE username like 'bob'"; 
+0

Questa non è davvero una buona idea. Non dovresti crittografare le password, dovresti eseguirne l'hash (se qualcuno ha hackerato il tuo server avrebbe accesso completo a tutte le password degli utenti). Stai anche implicando l'iniezione di SQL attraverso l'assenza di escape. – igorw

+0

Prima di tutto, rendo conto che le stringhe sono aperte a SQL injection; tuttavia questo non era l'argomento della discussione. Le istruzioni sql sono solo esempi e presumo che si rendano conto della necessità di disinfettare il loro input da parte dell'utente. Non sono qui per scrivere l'applicazione per loro. Sono qui per rispondere a domande specifiche. –

+0

In secondo luogo, la crittografia a 2 vie è altrettanto sicura di "hashing" se si tiene la chiave al sicuro. Mi rendo conto che se qualcuno ha hackerato il tuo server hanno le loro password, MA se qualcuno ha hackerato il tuo server, hanno accesso a tutto, incluse tutte le altre informazioni nel database, quindi le password di hashing diventano un punto controverso non credi? –

Problemi correlati