SHA1 vs md5 vs SHA256: ¿cuál usar para iniciar sesión en PHP?


133

Estoy haciendo un inicio de sesión de php, y estoy tratando de decidir si usar SHA1 o Md5, o SHA256 que leí en otro artículo de stackoverflow. ¿Alguno de ellos es más seguro que otros? Para SHA1 / 256, ¿sigo usando una sal?

Además, ¿es esta una forma segura de almacenar la contraseña como un hash en mysql?

function createSalt()
{
    $string = md5(uniqid(rand(), true));
    return substr($string, 0, 3);
}

$salt = createSalt();

$hash = sha1($salt . $hash);


Vea también esta respuesta y lea la sección sobre hashing de contraseñas.
Ja͢ck

Respuestas:


110

Ninguno. Debe utilizar bcrypt. Los hashes que menciona están optimizados para ser rápidos y fáciles en el hardware, por lo que descifrarlos comparten las mismas cualidades. Si no tiene otra opción, al menos asegúrese de usar una sal larga y vuelva a hacer picadillo varias veces.

Usando bcrypt en PHP 5.5+

PHP 5.5 ofrece nuevas funciones para el hash de contraseñas . Este es el enfoque recomendado para el almacenamiento de contraseñas en aplicaciones web modernas.

// Creating a hash
$hash = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]);
// If you omit the ['cost' => 12] part, it will default to 10

// Verifying the password against the stored hash  
if (password_verify($password, $hash)) {
    // Success! Log the user in here.
}

Si está utilizando una versión anterior de PHP , realmente debería actualizar , pero hasta que lo haga, puede usar password_compat para exponer esta API.

Además, por favor, deja password_hash()generar la sal por ti. Utiliza un CSPRNG .

Dos advertencias de bcrypt

  1. Bcrypt truncará en silencio cualquier contraseña de más de 72 caracteres.
  2. Bcrypt se truncará después de cualquier NULcarácter.

( Prueba de concepto para ambas advertencias aquí.)

Es posible que sienta la tentación de resolver la primera advertencia mediante un hash previo de sus contraseñas antes de ejecutarlas en bcrypt , pero hacerlo puede hacer que su aplicación se ejecute de cabeza en la segunda.

En lugar de escribir su propio esquema, use una biblioteca existente escrita y / o evaluada por expertos en seguridad.

TL; DR - Use bcrypt .


1
Además, soy muy nuevo en esto: ¿son sha1, sha256 y md5 todos los 'hashes' a los que te refieres?
Tony Stark

3
Si. Me refiero a SHA1, SHA256 y MD5 y una serie de otros hashes que están optimizados para la velocidad. No desea utilizar un hash optimizado para la velocidad para asegurar una contraseña. Hay muchos buenos artículos que discuten por qué, y me gusta este en particular: chargen.matasano.com/chargen/2007/9/7/…
Johannes Gorset

44
Está incluido en la función "cripta" desde PHP 5.3. Si tiene una versión anterior, buscaría en el marco "phpass" para la próxima mejor opción.
Johannes Gorset

3
@Stanislav Palatnik SHA512 es una buena alternativa. No me malinterpretes; No estoy diciendo que un hash SHA512 estirado y salado sea inseguro. Es seguro Aun así, el hecho es que bcrypt es más seguro, por lo que no veo ninguna razón para no usarlo.
Johannes Gorset

10
@Cypher: bcryptestá diseñado para ser lento en el interés de ser igualmente lento para crackear.
Johannes Gorset

23

Creo que usar md5 o sha256 o cualquier hash optimizado para la velocidad está perfectamente bien y tengo mucha curiosidad por escuchar cualquier refutación que otros usuarios puedan tener. Estas son mis razones.

  1. Si permite que los usuarios usen contraseñas débiles como Dios, amor, guerra, paz, sin importar el cifrado, aún permitirá que el usuario escriba la contraseña, no el hash, y estas contraseñas se usan a menudo primero, por lo tanto esto NO va tener algo que ver con el cifrado.

  2. Si no está utilizando SSL o no tiene un certificado, los atacantes que escuchen el tráfico podrán extraer la contraseña y cualquier intento de cifrar con JavaScript o similar es del lado del cliente y se puede descifrar y superar fácilmente. De nuevo, esto NO es tendrá nada que ver con el cifrado de datos en el lado del servidor.

  3. Los ataques de fuerza bruta aprovecharán las contraseñas débiles y nuevamente porque le permite al usuario ingresar los datos si no tiene la limitación de inicio de sesión de 3 o incluso un poco más, entonces el problema nuevamente NO tendrá nada que ver con el cifrado de datos.

  4. Si su base de datos se ve comprometida, lo más probable es que todo se haya visto comprometido, incluidas sus técnicas de hash, sin importar cuán críptico lo haya hecho. Nuevamente, esto podría ser un ataque de empleado XSS descontento o inyección de SQL o algún otro ataque que no tiene nada que ver con el cifrado de su contraseña.

Creo que aún debe encriptar, pero lo único que puedo ver es que las personas que ya tienen o de alguna manera obtuvieron acceso a la base de datos simplemente leen en voz alta la contraseña. Si hay alguien no autorizado en la base de datos, entonces tiene que preocuparse de los problemas más importantes, por eso Sony lo tomó porque pensó que una contraseña cifrada protegía todo, incluidos los números de tarjeta de crédito, todo lo que hace es proteger ese campo.

El único beneficio puro que puedo ver para los cifrados complejos de contraseñas en una base de datos es retrasar a los empleados u otras personas que tienen acceso a la base de datos simplemente leyendo las contraseñas. Entonces, si se trata de un proyecto pequeño o algo por el que no me preocuparía demasiado la seguridad en el lado del servidor, me preocuparía más por proteger cualquier cosa que un cliente pueda enviar al servidor, como inyección SQL, ataques XSS o la gran cantidad de otras formas en que Podría estar comprometido. Si alguien no está de acuerdo, espero leer una forma en que una contraseña súper encriptada es imprescindible desde el lado del cliente.

La razón por la que quería intentar aclarar esto es porque con demasiada frecuencia las personas creen que una contraseña cifrada significa que no tienen que preocuparse de que se vea comprometida y dejan de preocuparse por proteger el sitio web.


1
Bien dicho Se preferirá la seguridad cibernética a las técnicas de hashing, no solo guardan sus datos, sino que también mantienen lista la defensa del servidor.
CᴴᴀZ

14
Esto está realmente mal informado. Por supuesto, las contraseñas de hash de forma segura en la base de datos no mejoran la seguridad a nivel de aplicación o de base de datos. No es una trampa para la seguridad. Desea hash de forma segura la contraseña de usuario en su base de datos por 2 razones; primero, el cliente confía en usted con su contraseña, que puede o no usar en otros sitios, por lo que debe asegurarse de que esto no sea recuperable, incluso si db está comprometido, segundo, desea eliminar la responsabilidad en caso de seguridad incumplimiento. No conozco ninguna demanda de antemano, pero filtrar contraseñas hace que su empresa se vea realmente mal.
James McMahon

66
Este es un mal consejo. Si alguien roba su base de datos y obtiene todas sus contraseñas hash, incluso si también han comprometido otras partes de su base de datos, puede ser importante evitar que descifren las contraseñas e inicien sesión. (Piense en un sitio web bancario, por ejemplo). Los algoritmos de velocidad optimizada permiten a los atacantes probar a muchos candidatos contra los hashes robados hasta que encuentren una coincidencia. Algoritmos como bcrypt y scrypt hacen que sea lento y costoso evaluar a los candidatos contra el hash, incluso si saben qué algoritmo usas. Por lo tanto, brindan una mejor protección si alguien roba los hash.
Richard

66
"Si su base de datos se ve comprometida, lo más probable es que todo se haya visto comprometido, incluidas sus técnicas de hash, sin importar cuán críptico lo haya hecho". Es por eso que bcrypt es tan importante. Con bcrypt, realmente no importa si alguien tiene los hash. Con un algoritmo de hashing rápido como SHA1 / MD5, lo hace.
ceejayoz 01 de

Creo que el punto que algunos de ustedes se están perdiendo es que no importa si la contraseña es 1000% segura cuando todos los demás datos son de texto claro. Por ejemplo, si toda la base de datos se ve comprometida, entonces el hacker ahora tiene todos los números de tarjeta de crédito en texto claro. Sí, muchas personas usan la misma contraseña en diferentes sitios web, pero ya se les ha dicho ad nauseum que no lo hagan, por lo que ya no es nuestro problema. Si la base de datos contiene información confidencial y su compromiso es preocupante, encripte toda la base de datos, tan fuerte como crea necesario.
UncaAlby

15

Como señaló Johannes Gorset, la publicación de Thomas Ptacek de Matasano Security explica por qué las funciones simples de hash de propósito general como MD5, SHA1, SHA256 y SHA512 son malas opciones de hashing de contraseñas .

¿Por qué? Son demasiado rápidos: puede calcular al menos 1,000,000 hashes MD5 por segundo por núcleo con una computadora moderna, por lo que la fuerza bruta es factible contra la mayoría de las contraseñas que usan las personas. ¡Y eso es mucho menos que un clúster de servidores de craqueo basado en GPU!

Salar sin estirar la tecla solo significa que no puede calcular previamente la tabla del arco iris, debe construirla ad hoc para esa sal específica. Pero realmente no hará las cosas mucho más difíciles.

El usuario @ Will dice:

Todo el mundo habla de esto como si pudieran ser pirateados a través de Internet. Como ya se dijo, limitar los intentos hace que sea imposible descifrar una contraseña en Internet y no tiene nada que ver con el hash.

No necesitan hacerlo. Aparentemente, en el caso de LinkedIn , utilizaron la vulnerabilidad de inyección SQL común para obtener la tabla de base de datos de inicio de sesión y descifraron millones de contraseñas sin conexión.

Luego vuelve al escenario de ataque fuera de línea:

La seguridad realmente entra en juego cuando toda la base de datos se ve comprometida y un hacker puede realizar 100 millones de intentos de contraseña por segundo contra el hash md5. SHA512 es aproximadamente 10,000 veces más lento.

No, SHA512 no es 10000 veces más lento que MD5, solo toma aproximadamente el doble. Crypt / SHA512 , por otro lado, es una bestia muy diferente que, como su contraparte BCrypt, realiza estiramientos clave , produciendo un hash muy diferente con una sal aleatoria incorporada y tomará cualquier cosa entre 500 y 999999 veces más para calcular (estiramiento es sintonizable).

SHA512 => aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d
Crypt/SHA512 => $6$rounds=5000$usesomesillystri$D4IrlXatmP7rx3P3InaxBeoomnAihCKRVQP22JZ6EY47Wc6BkroIuUUBOov1i.S5KPgErtP/EN5mcO.ChWQW21

Entonces, la opción para PHP es Crypt / Blowfish (BCrypt), Crypt / SHA256 o Crypt / SHA512. O al menos Crypt / MD5 (PHK). Ver www.php.net/manual/en/function.crypt.php


El hash de contraseña simple está bien, depende del firewall mantener el servidor seguro ... y por "firewall" me refiero a un firewall reactivo que bloquea / ralentiza la fuerza bruta (un humano solo puede escribir ESO rápido) ... esto el concurso no tiene sentido ... "y si un pirata informático entró y ahora tiene todo" (escritorio), si un pirata informático entró en su servidor, se acabó. Las contraseñas se descifran principalmente porque son demasiado simples, o los desarrolladores de software son demasiado flojos para pensar como un ciberdelincuente.

@argon Por favor lea de nuevo. El propósito completo de las contraseñas hash es que cuando su base de datos de inicio de sesión se vea comprometida (y lo hará en algún momento) no se filtren de inmediato todas las contraseñas de sus usuarios, que los usuarios reutilizan con mayor frecuencia en diferentes sitios; de lo contrario, un simple retraso después de la entrada haría. Y el "juego sobre si tienen en su servidor" es un punto discutible, porque no se necesitan para obtener el interior de su servidor. La vulnerabilidad más común que usan los piratas informáticos ha sido la inyección de SQL (ver el caso de Linkedin), luego aplican fuerza bruta al hash. Es por eso que necesitas salazón y estiramiento.
LexLythius

Si el requisito de seguridad es realmente tan intenso, puede ser una buena idea almacenar contraseñas en otro lugar. Hay muchas maneras de proteger sus datos (y el código fuente) -para "si / cuándo" ... .. -pero el cifrado de contraseñas de hasta "millones de bits" es tan seguro como: el creador de la contraseña / sistema invitado , la transmisión de datos y los humanos que prestan servicio al hardware del servidor. Dicho esto: NO estoy diciendo que el hashing sea inútil, sin embargo, estoy diciendo que si su solución es un hash más complicado, me temo que no funcionará en el futuro cercano, con respecto a las computadoras cuánticas.

El hash recursivo agrega trabajo / costo a cualquier intento de piratería. Cuantas más iteraciones, más difícil de descifrar, se podrían utilizar incluso hashes rápidos como SHA256. Las iteraciones deben ser aleatorias y pueden hacerse públicas. password_hash()muestra el costo en el hash mismo.
Victor Stoddard

@VictorStoddard Sí, puede rodar su propio esquema de hash y proporcionar estiramiento de clave ajustable. Pero, ¿por qué querrías hacer eso en lugar de usar algoritmos ya existentes y mucho más minuciosamente analizados que los expertos han creado y puesto a disposición exactamente para este propósito?
LexLythius

13

Uso SHA256. No es perfecto, ya SHA512que sería ideal para un hash rápido, pero fuera de las opciones, es la elección definitiva. Según cualquier tecnología de hashing, asegúrese de salar el hash para mayor seguridad.

Como una nota adicional, FRKT, por favor muéstrame dónde alguien puede romper fácilmente un hash SHA256 salado. Estoy realmente muy interesado en ver esto.

Edición importante:

En el futuro, utilícelo bcryptcomo un hash endurecido. Más información se puede encontrar aquí .


Editar en salazón:

Use un número aleatorio o una secuencia de bytes aleatoria, etc. Puede usar el campo único del registro en su base de datos como la sal también, de esta manera la sal es diferente por usuario.


1
Pero están optimizados para la velocidad, lo que significa que permiten el pirateo de fuerza bruta.
Arbales

66
El hecho es que esto es para asegurar una contraseña. Al usar un hash con sal, luego agregue un límite de 3 intentos en el sitio web, ralentiza sustancialmente los intentos de piratas informáticos (incluso los forzadores brutos). Usando cualquier cifrado puro, ahora tiene otro problema: asegurar la clave. Si se encuentra la clave, toda su base de datos se ve comprometida (si no se agrega sal). Hashes, sin embargo, nunca obtendrá la contraseña original del sistema, y ​​así es como debe ser.
Kyle Rosendo

1
Como se señaló, el problema con las series MD y SHA es que están optimizadas para la velocidad. Es inevitable que los hashes de esta naturaleza se vuelvan cada vez más inseguros a medida que evoluciona la informática.
Johannes Gorset

1
Todo se vuelve cada vez más malo / inseguro / etc. a medida que la informática evoluciona. Cuando SHA512, etc., sean pirateados, habrá algoritmos más seguros disponibles. Esta es la naturaleza de la informática en cualquier caso.
Kyle Rosendo

1
¿Cuál es una buena manera de hacer una sal en PHP? tiene un código de ejemplo? imagino que no debería elegir algo como 'jirafa'
Tony Stark

4

Lo que parece faltar a la gente es que si el hacker tiene acceso a la base de datos, probablemente también tenga acceso al archivo php que codifica la contraseña y probablemente pueda modificarlo para enviarle todos los combos de contraseña de nombre de usuario exitosos. Si no tiene acceso al directorio web, siempre puede elegir una contraseña para escribirla y escribirla en la base de datos. En otras palabras, el algoritmo hash realmente no importa tanto como la seguridad del sistema, y ​​al limitar los intentos de inicio de sesión también si no usa SSL, el atacante puede escuchar la conexión para obtener la información. A menos que necesite que el algoritmo tome mucho tiempo para calcular (para sus propios fines), SHA-256 o SHA-512 con una sal específica para el usuario debería ser suficiente.

Como medida de seguridad adicional, configure un script (bash, batch, python, etc.) o un programa y asígnele un nombre oscuro y haga que compruebe y vea si login.php ha cambiado (compruebe la marca de fecha / hora) y le envíe un correo electrónico si tiene Probablemente también debería registrar todos los intentos de inicio de sesión con derechos de administrador y registrar todos los intentos fallidos para iniciar sesión en la base de datos y recibir los registros por correo electrónico.


"Lo que parece faltar es que si el hacker tiene acceso a la base de datos, probablemente también tenga acceso al archivo php que tiene la contraseña ..." Esto no es cierto. Una de las vulnerabilidades más comunes es la inyección de SQL, que daría capacidad de lectura / escritura a la base de datos pero cero acceso al código PHP.
ceejayoz 01 de

Si tiene acceso al código, puede modificar y almacenar toda la contraseña que el usuario envía en un texto sin formato. Entonces no, si el código se ve comprometido, entonces GAME OVER.
magallanes

3

Todo el mundo habla de esto como si pudieran ser pirateados a través de Internet. Como ya se dijo, limitar los intentos hace que sea imposible descifrar una contraseña en Internet y no tiene nada que ver con el hash.

La sal es imprescindible, pero la complejidad o las múltiples sales ni siquiera importan. Cualquier sal por sí sola impide que el atacante use una mesa arcoiris prefabricada. Una sal única por usuario impide que el atacante cree una nueva tabla de arco iris para usar contra toda su base de usuarios.

La seguridad realmente entra en juego cuando toda la base de datos se ve comprometida y un pirata informático puede realizar 100 millones de intentos de contraseña por segundo contra el hash md5. SHA512 es aproximadamente 10,000 veces más lento. Una contraseña compleja con el poder de hoy podría tomar 100 años para aplicar fuerza bruta con md5 y tomaría 10,000 veces más con SHA512. Las sales no detienen la fuerza bruta en absoluto, ya que siempre deben conocerse, lo que si el atacante descargó su base de datos, probablemente estaría en su sistema de todos modos.


1

MD5 es malo debido a problemas de colisión: dos contraseñas diferentes posiblemente generan el mismo md-5.

Sha-1 sería bastante seguro para esto. La razón por la que almacena la versión salada sha-1 de la contraseña es para que usted, el swerver, no guarde la contraseña del usuario en el archivo, que pueda estar usando con los servidores de otras personas. De lo contrario, ¿qué diferencia hace?

Si el pirata informático roba toda su base de datos sin cifrar de alguna manera, lo único que hace una contraseña con sal cifrada es evitar que se haga pasar por el usuario para futuros inicios de sesión: el pirata informático ya tiene los datos.

¿De qué le sirve al atacante tener el valor hash, si lo que su usuario ingresa es una contraseña simple?

E incluso si el hacker con tecnología futura pudiera generar un millón de claves sha-1 por segundo para un ataque de fuerza bruta, ¿su servidor manejaría un millón de inicios de sesión por segundo para que el hacker pruebe sus claves? Eso es si está permitiendo que el hacker intente iniciar sesión con el sha-1 salado en lugar de una contraseña como un inicio de sesión normal.

La mejor opción es limitar los intentos de inicio de sesión incorrectos a un número razonable, por ejemplo, 25, y luego agotar el tiempo del usuario por un minuto o dos. Y si los intentos acumulativos de inicio de sesión de bady llegan a 250 en 24 horas, cierre el acceso a la cuenta y envíe un correo electrónico al propietario.


Incluso si estoy usando un cifrado más débil, prácticamente ningún sistema puede contener un ataque bruto durante más de 1 millón de intentos por segundo.
magallanes

1
Tres inicios de sesión fallidos y estás bloqueado. Período, fin de la historia. Incluso las contraseñas súper estúpidas como "1234" son seguras, si el hacker intenta primero "contraseña", "pa $$ word" y "passw0rd" (¡bloquee!). La forma en que el usuario recupera el acceso ahora se convierte en su punto de seguridad, y lo que haga depende del tamaño de su base de usuarios. 200 usuarios? Pídales que llamen por teléfono para pedir ayuda.
UncaAlby

¿Esta respuesta no tiene sentido para nadie más, o solo soy yo?
Comodín el

1

Aquí está la comparación entre MD5 y SHA1. Puede tener una idea clara sobre cuál es mejor.

ingrese la descripción de la imagen aquí


1

Usa argón2i . La función de hash de contraseña de argon2 ha ganado la competencia de hash de contraseña.

Otras opciones razonables, si el uso de argon2 no está disponible, son scrypt , bcrypt y PBKDF2 . Wikipedia tiene páginas para estas funciones:

MD5, SHA1 y SHA256 son resúmenes de mensajes, no funciones de hash de contraseña. No son adecuados para este propósito.

Cambiar de MD5 a SHA1 o SHA512 no mejorará tanto la seguridad de la construcción. Calcular un hash SHA256 o SHA512 es muy rápido. Un atacante con hardware común aún podría probar decenas de millones (con una sola CPU) o incluso miles de millones (con una sola GPU) de hashes por segundo. Las buenas funciones de hash de contraseña incluyen un factor de trabajo para ralentizar los ataques de diccionario.

Aquí hay una sugerencia para los programadores de PHP: lea las preguntas frecuentes de PHP y luego use password_hash () .


0

Supongamos el siguiente punto: los piratas informáticos roban nuestra base de datos, incluidos los usuarios y la contraseña (cifrados). Y los hackers crearon una cuenta falsa con una contraseña que conocen.

MD5 es débil porque es corto y popular y prácticamente todas las generaciones de hash sin contraseña son débiles de un ataque de diccionario. Pero..

Entonces, digamos que todavía estamos usando MD5 con un SALT. Los hackers no conocen la SALT pero conocen la contraseña de un usuario específico. Para que puedan probar: ????? 12345 donde 12345 es la contraseña conocida y ????? es la sal Los piratas informáticos tarde o temprano pueden adivinar la SALT.

Sin embargo, si utilizamos un MD5 + SALT y aplicamos MD5, entonces no hay forma de recuperar la información. Sin embargo, repito, MD5 todavía es corto.

Por ejemplo, supongamos que mi contraseña es: 12345. La SALT es BILLCLINTON

md5: 827ccb0eea8a706c4c34a16891f84e7b

md5 con el hash: 56adb0f19ac0fb50194c312d49b15378

mD5 con el hash sobre md5: 28a03c0bc950decdd9ee362907d1798a Intenté usar esos servicios en línea y no encontré ninguno que pudiera descifrarlo. ¡Y es solo MD5! (puede ser como hoy será crackeable porque generé el md5 en línea)

Si desea exagerar, SHA256 es más que suficiente si se aplica con sal y dos veces.

tldr MD5 (HASH + MD5 (contraseña)) = ok pero corto, SHA256 es más que suficiente.


El problema con el uso de MD5 con sal es que las computadoras pueden crear un ataque de fuerza bruta en la contraseña con velocidades súper rápidas. shylor.com/2015/09/14/php-5-5-secure-password-hashing
Shylor

0

Un cifrado md5 es uno de los peores, porque tiene que activar el código y ya está descifrado. Te recomendaría el SHA256. Estoy programando un poco más y he tenido una buena experiencia. A continuación también habría un cifrado.

password_hash() example using Argon2i

<?php
echo 'Argon2i hash: ' . password_hash('rasmuslerdorf', PASSWORD_ARGON2I);
?>
The above example will output something similar to:

Argon2i hash: $argon2i$v=19$m=1024,t=2,p=2$YzJBSzV4TUhkMzc3d3laeg$zqU/1IN0/AogfP4cmSJI1vc8lpXRW9/S0sYY2i2jHT0
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.