2012-10-13 230 views
5

Estoy usando el formato simple md5($password);, pero quiero agregar sal, así que ¿cómo puedo hacer eso?¿Cómo agregar sal en la contraseña del usuario?

aquí es mi código:

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

Lea: [Lo que debe saber sobre la seguridad de las contraseñas] (http://crackstation.net/hashing-security.htm) – NullUserException

+0

Gracias, lo estoy revisando – deerox

+0

Me gustaría recomendar no usar md5, sino más bien un algoritmo de hash moderno. – Aleph

Respuesta

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

Cuanto más larga, más compleja y única para cada usuario puede hacer la sal, más difícil será para que cualquiera pueda obtener la contraseña (aunque no es imposible)

A (sal, pero pobres) simple sería: $salt = '10';
Una sal mucho más fuerte sería: $salt = '-45dfeHK/[email protected]/klF21-1_\/4JkUP/4';

sales que son únicos para el usuario son aún mejores.

Como se mencionó en varios comentarios, md5 es un viejo y relativamente pobre algoritmo hash, SHA-512 o cualquiera de la familia SHA-2 sería una opción mucho mejor.

Consulte this salting question para obtener más información.

+0

Gracias, ahora será perfecto – deerox

+0

Mal karma para usar MD5. – Sven

+0

Buen punto, solo lo usé porque la pregunta sí, lo agregaré a mi respuesta. – SteB

0

Aquí se muestra un ejemplo: (Use su contraseña aquí)

$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

Voy a probar algo como esto gracias :) – deerox

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

Otras personas han mostrado cómo se puede hacer, por lo que sobre los principios en general ...

Como ya se vinculado por NullUserException en los comentarios, no debe hacerlo simplemente agregando una sal estática a md5, si la seguridad es importante. Note however that you can store your salt as-is. Tanto la sal estática como md5 no se consideran enfoques muy seguros. Están bien si no importa mucho, pero si lo hace, deberías ir por el otro lado.

About static salt:

Un error común es el uso de la misma sal en cada hash. O la sal está codificada en el programa, o se genera aleatoriamente una vez. Esto es ineficaz porque si dos usuarios tienen la misma contraseña, todavía tendrán tienen el mismo hash. Un atacante aún puede usar un ataque de tabla de búsqueda inversa para ejecutar un ataque de diccionario en cada hash al mismo tiempo. Ellos solo tienen que aplicar la sal a cada contraseña adivinar antes de que ellos lo hagan . Si la sal está codificada de forma rígida en un producto popular, las tablas de búsqueda y las tablas de arcoiris se pueden construir para esa sal, para facilitar hashes de grieta generados por el producto.

Se debe generar un nuevo sal aleatorio cada vez que un usuario cree una cuenta o cambie su contraseña.

Si la sal es estática, un atacante solo puede generar una tabla de arcoíris para todas las posibilidades. Con una sal que es exclusiva de un usuario, no tiene sentido hacer eso.

md5 está diseñado para la velocidad computacional, por lo que es fundamentally not the way to go. Además, ya hay un montón de pre-created rainbow tables para él, y un montón de online cracking tools.

La página vinculada contiene PHP source code, también, como un ejemplo de cómo hacerlo correctamente.

<?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

esto es realmente útil comentar muchas gracias – deerox

+0

Yo usaría bcrypt sobre PBKDF2 en php – CodesInChaos

2

PHP 5.5 traerá una muy fácil de usar API de hash de contraseñas, y actualmente se reimplantado para ser utilizado de inmediato con PHP a partir de la versión 5.3.7.

pude copiar & pegar la explicación, pero ver por sí mismo: https://github.com/ircmaxell/password_compat

En resumen, es la siguiente:

/* 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 */ 
    } 
} 

El hash podría ser de hasta 255 caracteres (no con bcrypt, pero sea lo que sea lo que venga después), planifique el almacenamiento en consecuencia. Las bases de datos deben usar VARCHAR (255).

Cuestiones relacionadas