¿Cuál es la forma correcta de hacer un salt de contraseña?

1

He hecho la siguiente función para hacer un hash de 64 caracteres completamente aleatorio

   function password_salt($password){
    $salt = hash("sha512", mt_rand(1,100000) . strtotime("now") . $password . "ewuwmeqwjkeq 7689" . hash("sha256", strtotime("now - 10 days") . $password));
    $salt = $salt . $password;
    for ($i=0;$i<10000;$i++){
        $salt = hash("sha512",$salt);
    }
    $hash = $salt . $password;
    for ($i=0;$i<10000;$i++){
        $hash = hash("sha512",$hash);
    }
    $salt = hash("sha512", mt_rand(1,100000) . strtotime("now") . $password . $hash . "ewuwmeqwjkeq 7689" . hash("sha256", strtotime("now - 10 days") . $hash . $salt) . $salt);

    //salt is almost ready for production
    // go salt part 2
    $salt2 = hash("sha512", $salt . $salt . $salt . $password . mt_rand(1,100000) . "dsjdj3y87Yhuu(&^TYUGh" . hash("sha512", $salt . $salt . $password . $salt));

    //hash salt . salt2 . salt . salt2 . salt2 . hash salt2 timestamp
    $salt = hash("sha512", $salt . $salt2 . uniqid(rand(), true) . $salt . $salt2 . $salt2 . hash("sha512", $salt2 . strtotime("now")));

    // go salt 3
    $salt3 = hash("sha512", $salt2 . $salt . $salt2 . $password . mt_rand(1,100000) . "DMDJ3908_))O l;[h" . hash("sha512", $salt . $salt2 . $password . $salt2));

    //final salt
    $salt = hash("sha512", $salt3 . $salt2 . $salt . $salt2 . $salt3 . hash("sha512", $salt3 . strtotime("now - 1 day") . uniqid(rand(), true)) . uniqid(rand(), true));

    echo "Salt: ". $salt . "<br><br>";
}

¿Es esta función lo suficientemente buena como para hacer una sal segura?

    
pregunta Ben Johnson mk2 23.02.2014 - 18:11
fuente

3 respuestas

6

Con un enfoque independiente del lenguaje, se recomienda utilizar técnicas bien probadas y probadas en el tiempo para hash seguro de sus contraseñas (o cualquier problema relacionado con criptografía, para eso importa) en lugar de crear su propia contraseña.

¿Por qué? Porque usted, por definición, es un cerebro. La mayoría de las veces, un cerebro no detecta sus propios errores hasta que es demasiado tarde. Tres cerebros es mejor, y cuatro aún mejor. Dichas bibliotecas pueden tener entre diez y miles de personas que trabajan en ellas y / o intentan romperlas.

Ya que estás usando PHP, recomiendo usar bibliotecas que tengan poca curva de aprendizaje y que hagan todo por ti (generando la sal, el hashing y la verificación) como PHPass . Si tiene el lujo de codificar solo para PHP 5.5, entonces puede usar la API propia de PHP para eso (marque password_hash ).

Finalmente, para responder a tu pregunta directamente, si solo quieres generar una cadena hexagonal de 64 caracteres (un gigante de 256 bits), te recomiendo usar algo como esto:

$salt = bin2hex(openssl_random_pseudo_bytes(32));

Nota: Si bien 256 bits es fantástico, creo que es demasiado para una sal. Recomiendo ir con 128 bits (16 bytes), lo que producirá una cadena hexadecimal de 32 caracteres.

    
respondido por el Adi 23.02.2014 - 19:16
fuente
3

Primero, como han mencionado todas las demás respuestas y sin duda alguna, lea ¿Cómo hacer hash de forma segura las contraseñas? , y quizás también la advertencia de no seas un Dave .

Para abordar la pregunta real, para generar un salt, simplemente use un conocido generador de pseudorandom de criptografía segura para, sin embargo. Muchos bytes que desee de salida binaria. El hash de un PRNG no criptográficamente seguro no lo hace en sí mismo como un CSPRNG (ver ¿El hashing de un PRNG lo hace criptográficamente seguro? ).

Ya sea que termine usando PBKDF2, Bcrypt o Scrypt, el proceso de hashing de contraseñas opera con valores binarios, por lo que un salt binario le da la mayor aleatoriedad por byte de almacenamiento, es decir, puede almacenar 8 bytes de datos binarios, o Cadena de 16 bytes que codifica esos mismos 8 bytes de datos binarios en hexadecimal (etc.). Cada método de almacenamiento que no sea binario ocupa un almacenamiento adicional.

Por supuesto, puede usar otras codificaciones; siga la implementación conocida que elija.

Algunos ejemplos de CSPRNG encontrados por una búsqueda de Google en "crypto RNG [language]" incluyen:

Tenga en cuenta que es posible que desee realizar más investigaciones sobre las versiones de Perl y Ruby, ya que no busqué la confirmación de un tercero, y los PRNG criptográficos son difíciles de validar (consulte la historia de advertencia de Dual_EC_DRBG en NIST SUPLEMENTAL BOLETÍN DE ITL PARA SEPTIEMBRE DE 2013

    
respondido por el Anti-weakpasswords 24.02.2014 - 01:31
fuente
-1

Estás usando SHA-512, que no se recomienda para sales. En lugar de escribir su propia lógica para iterarla repetidamente, y tal vez desordenarla (lo que es increíblemente fácil de hacer), debería usar bcrypt (o algo similar). Mire la respuesta a esta pregunta .

    
respondido por el Mike Scott 23.02.2014 - 18:20
fuente

Lea otras preguntas en las etiquetas