2012-10-13 11 views
5

Sto usando il semplice formato md5($password); ma voglio aggiungere il sale così come posso farlo?Come aggiungere sale nella password utente?

Ecco il mio codice:

if($success) 
    { 
     $data['firstname'] = $firstname; 
     $data['lastname'] = $lastname; 
     $data['username'] = $username; 
     $data['password'] = md5($password); 
     $data['email'] = $email; 


     $newUser = new User($data); 
     $newUser->save(true); 
     $Newuser->login($username, $password); 
     header("Location: welcome.php"); 

    } 
+3

Leggi: [Che cosa dovresti sapere sulla sicurezza della password] (http://crackstation.net/hashing-security.htm) – NullUserException

+0

Grazie sto passando attraverso di esso – deerox

+0

Mi piacerebbe raccomandare di non usare md5, ma piuttosto un altro algoritmo di hashing moderno. – Aleph

risposta

7
$data['hashedpwd'] = md5($salt . $password); 

Più lungo, più complesso e unico per ogni utente è possibile rendere il sale più difficile sarà per chiunque di ottenere la password (anche se non è impossibile).

A (sale ma povero) semplice sarebbe: $salt = '10';
Un sale molto più forte sarebbe: $salt = '-45dfeHK/[email protected]/klF21-1_\/4JkUP/4';

sali che sono unici per l'utente sono ancora meglio.

Come menzionato in diversi commenti md5 è un algoritmo di hashing vecchio e relativamente scadente, SHA-512 o una qualsiasi delle famiglie SHA-2 sarebbero scelte molto migliori.

Vedere this salting question per ulteriori dettagli.

+0

Grazie sarà perfetto ora – deerox

+0

Karma negativo per l'utilizzo di MD5. – Sven

+0

Buon punto, l'ho usato solo perché la domanda è stata, aggiungerò alla mia risposta. – SteB

0

Ecco un esempio: (Utilizzare la password qui)

$pass = 'abcxyz123'; // password 
    $salt = '}#f4ga~g%7hjg4&j(7mk?/!bj30ab-wi=6^7-$^R9F|GK5J#E6WT;IO[JN'; // random string 

    $hash = md5($pass); 
    $hash_md5 = md5($salt . $pass); 

    // echo now 
    echo 'Original Password: ' . $pass . '<br><br>'; 
    echo 'Original Salt: ' . $salt . '<br><br>'; 
    echo 'MD5: ' . $hash . '<br><br>'; 
    echo 'MD5 with Salt: ' . $hash_md5 . '<br><br>'; 
+0

Proverò qualcosa di simile grazie :) – deerox

1
$salt="Your text vatiable"; 
$data[passsord] = md5($salt . $password); 
2

Altre persone hanno dimostrato come si può fare, quindi circa i principi in generale ...

Come già collegato da NullUserException nei commenti, non dovresti farlo aggiungendo un salt statico a md5, se la sicurezza è importante. Note however that you can store your salt as-is. Sia il sale statico che il md5 non sono considerati approcci molto sicuri. Sono ok se non importa così tanto, ma se lo fa, dovresti andare dall'altra parte.

About static salt:

Un errore comune è quello di utilizzare lo stesso sale in ogni hash. O il sale è hard-coded nel programma, o è generato casualmente una volta. Questo è inefficace perché se due utenti hanno la stessa password, avranno ancora lo stesso hash. Un utente malintenzionato può ancora utilizzare un attacco della tabella di ricerca inversa per eseguire un attacco di dizionario su ogni hash nello stesso momento. Loro devono solo applicare il sale a ogni indovina password prima che l'hash esso. Se il sale è hard-coded in un prodotto popolare, le tabelle di ricerca e le tabelle arcobaleno possono essere create per tale sale, per semplificare l'operazione di crack hasha generato dal prodotto.

Un nuovo salt casuale deve essere generato ogni volta che un utente crea un account o modifica la password.

Se il sale è statico, un attaccante può solo generare una tabella arcobaleno per tutte le possibilità. Con un sale che è unico per un utente, non ha senso farlo.

md5 è progettato per la velocità di calcolo, quindi è fundamentally not the way to go. Inoltre, c'è già molto pre-created rainbow tables per questo, e un sacco di online cracking tools.

La pagina collegata contiene anche PHP source code come esempio di come farlo correttamente.

<?php 
/* 
* Password hashing with PBKDF2. 
* Author: havoc AT defuse.ca 
* www: https://defuse.ca/php-pbkdf2.htm 
*/ 

// These constants may be changed without breaking existing hashes. 
define("PBKDF2_HASH_ALGORITHM", "sha256"); 
define("PBKDF2_ITERATIONS", 1000); 
define("PBKDF2_SALT_BYTES", 24); 
define("PBKDF2_HASH_BYTES", 24); 

define("HASH_SECTIONS", 4); 
define("HASH_ALGORITHM_INDEX", 0); 
define("HASH_ITERATION_INDEX", 1); 
define("HASH_SALT_INDEX", 2); 
define("HASH_PBKDF2_INDEX", 3); 

function create_hash($password) 
{ 
    // format: algorithm:iterations:salt:hash 
    $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM)); 
    return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" . $salt . ":" . 
     base64_encode(pbkdf2(
      PBKDF2_HASH_ALGORITHM, 
      $password, 
      $salt, 
      PBKDF2_ITERATIONS, 
      PBKDF2_HASH_BYTES, 
      true 
     )); 
} 

function validate_password($password, $good_hash) 
{ 
    $params = explode(":", $good_hash); 
    if(count($params) < HASH_SECTIONS) 
     return false; 
    $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]); 
    return slow_equals(
     $pbkdf2, 
     pbkdf2(
      $params[HASH_ALGORITHM_INDEX], 
      $password, 
      $params[HASH_SALT_INDEX], 
      (int)$params[HASH_ITERATION_INDEX], 
      strlen($pbkdf2), 
      true 
     ) 
    ); 
} 

// Compares two strings $a and $b in length-constant time. 
function slow_equals($a, $b) 
{ 
    $diff = strlen($a)^strlen($b); 
    for($i = 0; $i < strlen($a) && $i < strlen($b); $i++) 
    { 
     $diff |= ord($a[$i])^ord($b[$i]); 
    } 
    return $diff === 0; 
} 

/* 
* PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt 
* $algorithm - The hash algorithm to use. Recommended: SHA256 
* $password - The password. 
* $salt - A salt that is unique to the password. 
* $count - Iteration count. Higher is better, but slower. Recommended: At least 1000. 
* $key_length - The length of the derived key in bytes. 
* $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise. 
* Returns: A $key_length-byte key derived from the password and salt. 
* 
* Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt 
* 
* This implementation of PBKDF2 was originally created by https://defuse.ca 
* With improvements by http://www.variations-of-shadow.com 
*/ 
function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false) 
{ 
    $algorithm = strtolower($algorithm); 
    if(!in_array($algorithm, hash_algos(), true)) 
     die('PBKDF2 ERROR: Invalid hash algorithm.'); 
    if($count <= 0 || $key_length <= 0) 
     die('PBKDF2 ERROR: Invalid parameters.'); 

    $hash_length = strlen(hash($algorithm, "", true)); 
    $block_count = ceil($key_length/$hash_length); 

    $output = ""; 
    for($i = 1; $i <= $block_count; $i++) { 
     // $i encoded as 4 bytes, big endian. 
     $last = $salt . pack("N", $i); 
     // first iteration 
     $last = $xorsum = hash_hmac($algorithm, $last, $password, true); 
     // perform the other $count - 1 iterations 
     for ($j = 1; $j < $count; $j++) { 
      $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true)); 
     } 
     $output .= $xorsum; 
    } 

    if($raw_output) 
     return substr($output, 0, $key_length); 
    else 
     return bin2hex(substr($output, 0, $key_length)); 
} 
+0

questo è davvero un commento molto utile grazie mille – deerox

+0

Io userei bcrypt su PBKDF2 in php – CodesInChaos

2

PHP 5.5 porterà un molto facile da usare la password hashing API, ed è attualmente reimplementato per essere utilizzato subito con PHP a partire da versione 5.3.7.

ho potuto copiare & incollare la spiegazione, ma vedere di persona: https://github.com/ircmaxell/password_compat

In breve, è come questo:

/* Create the hash */ 
$hash = password_hash($password, PASSWORD_BCRYPT, array('cost' => 10)); 

/* Store the hash... then user comes back */ 
if (password_verify($password, $hash)) { 
    /* Valid */ 
} else { 
    /* Invalid */ 
} 

/* 
* If the security level has to be increased to new $options or a new $algorithm, 
* silent rehashing is supported 
*/ 
if (password_verify($password, $hash)) { 
    if (password_needs_rehash($hash, $algorithm, $options)) { 
     $hash = password_hash($password, $algorithm, $options); 
     /* Store new hash in db */ 
    } 
} 

L'hash può essere lungo fino a 255 caratteri (non con bcrypt, ma qualunque cosa possa venire dopo), pianifica lo storage di conseguenza. I database dovrebbero usare VARCHAR (255).

Problemi correlati