2010-12-08 31 views
50

Estaba leyendo este tutorial para un simple PHP login system.¿Para qué es md5()?

Al final, se recomienda encrypt your password using md5().

Aunque sé que este es un tutorial para principiantes, y no debe poner estados de cuenta bancarios detrás de este sistema de inicio de sesión, esto me hizo pensar en el cifrado.

Así que siguió adelante y fue a (una de las preguntas más útiles de este sitio tiene para los novatos): What should a developer know before building a public web site?

Allí se dice (en la seguridad) debe:

Cifrar Hash y contraseñas de sal en lugar de almacenarlas en formato de texto sin formato .

No dice mucho más al respecto, no hay referencias.

Así que siguió adelante y probado a mí mismo:

$pass = "Trufa"; 
$enc = md5($pass); 

echo $enc; #will echo 06cb51ce0a9893ec1d2dce07ba5ba710 

Y esto es lo que me hizo pensar, que a pesar de que sé md5() podría no la manera más fuerte para cifrar, todo lo que siempre produce el mismo resultado puede ser ingeniería inversa.

Entonces, ¿cuál es el sentido de encriptar algo con md5() o cualquier otro método?

Si un pirata informático obtiene una contraseña cifrada con md5(), he would just use this page!.

por lo que ahora las preguntas reales:

  1. ¿Cómo funciona el cifrado de la contraseña?

Sé que no he descubierto una gran vulnerabilidad de la web aquí! :) Solo quiero entender la lógica detrás del cifrado de contraseñas.

Estoy seguro de que estoy entendiendo algo mal, y agradecería si pudieran ayudarme a establecer mi pensamiento y el de los demás (espero) directamente.

¿Cómo tendría que aplicar el cifrado de contraseña para que sea realmente útil?

  1. ¿Qué tal esta idea?

Como dije, es posible que me esté haciendo una idea equivocada, pero, ¿este método agregaría alguna seguridad en la seguridad a un entorno real?

$reenc = array(
"h38an", 
"n28nu", 
"fw08d" 
); 

$pass = "Trufa"; 

$enc = chunk_split(md5($pass),5,$reenc[mt_rand(0,count($reenc)-1)]); 

echo $enc; 

Como se puede ver, he añadido al azar cadenas arbitrarias ($reenc = array()) a mi md5() contraseña "lo que es único". Esto, por supuesto, es solo un ejemplo tonto.

Puede que esté equivocado, pero a menos que "inicie el cifrado usted mismo" siempre será fácilmente reversible.

Lo anterior sería mi idea de "protección de contraseña" y la contraseña encriptada, si un hacker consigue que él no será capaz de descifrarlo a menos que acceda a la .php prima

Sé que esto puede no incluso tiene sentido, ¡pero no puedo entender por qué esta es una mala idea!


espero que lo hecho fue lo suficientemente claro, pero esta es una pregunta muy largo, así que, por favor, solicitar cualquier aclaración necesaria!

Gracias de antemano!

+11

+1 Para no solo preguntar "¿Qué es md5() para?" – Gumbo

+6

lo que "inventó" ya existe. se llama SALT. "salar" un hash resulta en una mayor seguridad, sí. pero md5() es un poco obsoleto. tiene demasiadas colisiones y está desactualizado.use sha1() en su lugar – mark

+3

@Gumbo ¡Me ha sorprendido la buena voluntad y el esfuerzo que la gente le hace para responder cuando pone un poco de esfuerzo en sus preguntas! – Trufa

Respuesta

20

Debe tener un encryption como o sha512. También debe tener dos sales diferentes, un static salt (escrito por usted) y luego también un unique salt para esa contraseña específica.

algunos ejemplos de código (por ejemplo registration.php):

$unique_salt = hash('md5', microtime()); 
$password = hash('md5', $_POST['password'].'raNdoMStAticSaltHere'.$unique_salt); 

Ahora usted tiene una static salt, que es válido para todas sus contraseñas, que se almacena en el archivo .php. Luego, en la ejecución del registro, genera un unique hash para esa contraseña específica.

Todo esto termina con: dos contraseñas que se escriben exactamente igual, tendrán dos hashes diferentes. El unique hash se almacena en el database junto con la identificación actual. Si alguien toma el database, tendrá cada unique salt para cada contraseña específica. Pero lo que no tienen es su static salt, que hace las cosas mucho más difíciles para cada "hacker".

Así es como se comprueba la validez de la contraseña en login.php por ejemplo:

$user = //random username; 
$querysalt = mysql_query("SELECT salt FROM password WHERE username='$user'"); 
while($salt = mysql_fetch_array($querysalt)) { 
    $password = hash('md5', 
      $_POST['userpassword'].'raNdoMStAticSaltHere'.$salt[salt]); 
} 

Esto es lo que he usado en el pasado. Es muy poderoso y seguro. Yo prefiero la encriptación sha512. En realidad, es solo ponerlo dentro de la función hash en lugar de md5 en mi ejemplo.

Si quiere estar aún más seguro, puede almacenar el unique salt en una base de datos completamente diferente.

+0

Un punto importante acerca de esto es que si el atacante aprende la sal estática, sigue siendo al menos tan seguro como si no hubiera usado una sal estática en absoluto. – CodesInChaos

+0

@CodelnChaos: Sí. Seguir con esta solución que he hecho me ha ayudado; ya que los hackers no quieren usar desencriptadores para descubrir una sola sal (llevará semanas). Imagine que tiene una gran base de datos con muchos usuarios. – Wroclai

+0

@Charlie Ok, tan pronto como lo intente, ¡esto tiene mucho más sentido ahora! ¡Gracias! – Trufa

4

Te estás perdiendo el paso importante: la sal. Este es un bit único (por usuario, idealmente) de datos adicionales que agrega a la contraseña antes de hash.

http://en.wikipedia.org/wiki/Salt_%28cryptography%29

+0

No, la salazón está allí. –

+0

@Ignacio ¿estás hablando de mi "invención" o cuando haces md5()? – Trufa

+2

@Akinator: Su "invención" se llama "salazón del hash". –

5

La única vulnerabilidad con el salado es que lo que necesita saber lo que es la sal con el fin de reconstruir el hash para comprobar la contraseña. Esto se consigue almacenando la entrada en authdb en el formato <algorithm>$<salt>$<hash>. De esta forma, la entrada authdb puede ser utilizada por con cualquier código que tenga acceso.

+0

¡Estoy un poco perdido! ¡Podría seguir tu línea de razonamiento! ¡Lo siento! podría hacer que sea un poco más novato amigable? – Trufa

+0

Si almacena una contraseña de "hello" con una sal de "12345", su código (y todo el código que desee usar authdb) debe tener el código "12345" codificado para verificar la contraseña, ya que tiene que ajustar la contraseña y compararla con el hash almacenado. Si almacena la sal junto con el hash, entonces no necesita tenerlo codificado, y de hecho puede usar sales aleatorias de cualquier código que lo use. 'sha1 $ 12345 $ bighashgoeshere' –

+0

bien, ¡creo que ya veo tu punto! ¡Gracias! – Trufa

1

Además de proporcionar sal (o semilla), el md5 es un complejo algoritmo hash que usa reglas matemáticas para producir un resultado que no es específicamente reversible debido a los cambios matemáticos y el rendimiento en el rendimiento.

http://en.wikipedia.org/wiki/Cryptographic_hash_function

+0

¿Has visto mi enlace? http://md5.rednoize.com/ – Trufa

+0

@Akinator: lo siento, ese enlace está bloqueado en el firewall de mi empresa. –

+0

@Joel no hay problema, solo revierte hash md5 al instante. – Trufa

1

md5 (o mejor dicho: los algoritmos hash en general) se utilizan para almacenar de forma segura las contraseñas de la base de datos. Lo más importante que debe saber sobre los hash es: Los valores hash no son encriptados per se. (son encriptados unidireccionales como máximo). Si encriptas algo, puedes recuperar los datos con la clave que usaste. Un hash genera un valor de longitud fija a partir de una entrada arbitraria (como una cadena), que se puede usar para ver si se utilizó la misma entrada.

Los valores hash se utilizan para almacenar datos confidenciales y repetidamente ingresados ​​en un dispositivo de almacenamiento. Al hacer esto, nadie puede recrear la entrada original de los datos de hash, pero puede hash una contraseña entrante y compararla con el valor en la base de datos, y ver si ambas son iguales, si es así, la contraseña era correcta.

Usted ya ha señalado que existe la posibilidad de romper el algoritmo, ya sea utilizando una base de datos de pares valor/hash o produciendo colisiones (diferentes valores que dan como resultado el valor hash). Puede oscurecerlo un poco usando una sal, modificando así el algoritmo. Pero si se conoce la sal, se puede utilizar para romper el algoritmo de nuevo.

+0

Gracias entiendo tu punto con respecto a la parte SALT, ahora lo que no entiendo es por qué es exactamente lo que dices sobre md5, esto es exactamente lo que provocó mi pregunta, ¿por qué comparar "jfnvsv123" (contraseña hash) contra "jfnvsv123" cuando pudieras simplemente compare "123" contra "123" porque el hash es fácilmente reversible. – Trufa

+0

El punto es - no lo es. La razón por la que es fácilmente reversible radica en el hecho de que 'md5' (y también recientemente,' sha1') es bastante antiguo, y la única razón por la que no estaba rajado (como en: produciendo suficientes colisiones) era que las computadoras no no lo suficientemente rápido La página que vinculó no "descifra" la contraseña, usa una base de datos simple para buscarla. Si nadie más le suministró la entrada original antes, no obtendrá algo a cambio. – Femaref

+0

@ Ok, tiene sentido que no "descifre" el hash. En realidad, no funciona por "contraseñas" de pormenor – Trufa

6

MD5 es una función de hash unidireccional que protegerá su contraseña original de forma más o menos segura.

Entonces, digamos que su contraseña es "Trufa", y su versión hash es 06cb51ce0a9893ec1d2dce07ba5ba710.

Por ejemplo, cuando inicia sesión en una nueva página web, le piden su nombre de usuario y contraseña. Cuando escribe "Trufa" como su contraseña, el valor 06cb51ce0a9893ec1d2dce07ba5ba710 se almacena en la base de datos porque está codificado.

La próxima vez que inicie sesión y escriba "Trufa", el valor hash se comparará con el de la base de datos. Si son lo mismo, ¡estás autenticado!Siempre que haya ingresado el nombre de usuario correcto, por supuesto.

Si su contraseña no se almacenó en su forma hash en la base de datos, alguna persona malintencionada podría ejecutar una consulta de alguna manera en esa base de datos y ver todas las contraseñas reales. Y eso sería comprometedor.

Además, como MD5 es una función criptográfica de 128 bits, existen 2^128-1 = 340282366920938463463374607431768211455 combinaciones posibles.

Dado que hay más cadenas posibles que esto, es posible que 2 cadenas generen el mismo valor hash. Esto se llama colisión. Y se asegura de que una contraseña hash no pueda ser exclusiva ingeniería inversa.

+0

Te entiendo, ahora que he leído algunas buenas respuestas, esta me da una buena idea de lo que md5() es, aunque todavía me desconcierta, (si no SALT tu contraseña) ¿por qué md5() sería más seguro que una contraseña no encriptada? Supongamos que quiere protegerse contra un ataque de diccionario, qué bien sería, si el pirata informático, sabe que sus contraseñas son hasheadas, simplemente hojearía su diccionario y continuaría intentando, las colisiones lo retrasarían un poco. ver mi punto? Por cierto, ¿sabes qué tan alta es esta tasa de colisión? ¡Gracias por tu respuesta! – Trufa

+0

@Akinator: esto no brinda ninguna protección contra un ataque de estilo de diccionario (el atacante no necesita manipular sus intentos, simplemente le da a su sitio solicitudes). Aquí es donde combina esto con un recuento de la cantidad de intentos de inicio de sesión que recibe alguien (por ejemplo, 5) antes de que se bloqueen o temporalmente no puedan iniciar sesión durante un período establecido (digamos 30 minutos). – Paddy

+0

@Paddy está bien, pero probablemente me haya explicado mal. – Trufa

4

Su idea (salazón) es bien conocida y en realidad está bien implementada en el lenguaje PHP. Si usa the crypt() function, le permite especificar una cadena para hash, un método para encriptar (en algunos casos) y un salt. Por ejemplo,

$x = crypt('insecure_password', $salt); 

Devuelve una contraseña hash y salada lista para el almacenamiento. Las contraseñas se resquebrajan de la misma manera que comprobamos si son correctas: verificamos el hash de lo que el usuario ingresa contra el hash de su contraseña en la base de datos. Si coinciden, están autenticados (AFAIK esta es la forma más común de hacerlo, si no la única). Las contraseñas inseguras (como password) que usan palabras de diccionario se pueden descifrar al comparar su hash con hashes de contraseñas comunes. Las contraseñas seguras no se pueden descifrar de esta manera, pero aún se pueden descifrar. Agregar una sal a la contraseña hace que sea mucho más difícil de descifrar: dado que es probable que el hacker no sepa cuál es la sal, su ataque de diccionario no funcionará.

+0

Ok, ahora estoy empezando a entender. Explicación muy clara IMO. Gracias. – Trufa

18

En primer lugar, "hashing" (utilizando una función criptográfica unidireccional) no es "cifrado". En el cifrado, puede revertir el proceso (descifrado). En hashing, no existe (teóricamente) ninguna forma factible de revertir el proceso.

Un hash es alguna función f tal que v no puede determinarse desde f (v) fácilmente.

El objetivo de usar hash para la autenticación es que usted (o alguien que vea el valor de hash) no tenga ninguna forma factible (otra vez, teóricamente) de conocer la contraseña. Sin embargo, aún puede verificar que el usuario conoce su contraseña. (Básicamente, el usuario prueba que conoce v tal que f (v) es el hash almacenado).

La debilidad del hash simple (aparte de las funciones de hash débiles) es que la gente puede compilar tablas de contraseñas y su correspondiente hash y usarlas para (efectivamente) obtener el inverso de la función hash. La salazón evita esto porque luego se controla una parte del valor de entrada al hash y, por lo tanto, se deben compilar las tablas para esa sal en particular.

Prácticamente, almacenas un valor de sal y hash, y autenticas mezclando una combinación de la sal y la contraseña y comparando eso con tu valor hash.

+0

que ayuda! explicación agradable y simple, ¡gracias! – Trufa

+2

+1 para el uso correcto de los términos. – Axn

+3

+1 Agradecido de encontrar al menos un par de carteles que dicen que los hash no son una forma de encriptación. – Orbling

1

Me gusta esta pregunta. Pero creo que realmente te has respondido a ti mismo.

El sitio al que ha hecho referencia utiliza búsquedas de diccionario conocidas, sin sal, md5 - no "descifra" nada.

Su ejemplo es casi bueno, excepto que su aplicación necesita ser capaz de regenerar el md5 usando la misma sal siempre.

Su ejemplo parece utilizar una de las sales aleatorias, que fallarán 2 de 3 veces si intenta comparar el hash de contraseña de un usuario con algo ingresado.

La gente le dirá que también use SHA1 o SHA256 para tener un hash "más fuerte", pero las personas también argumentarán que están "rotas".

+0

Veo eso ahora, lo explicaste muy claramente gracias, pero no veo por qué NO usar sales aleatorias ayudará, digamos que obtengo toda la matriz del hash, ¿no sería suficiente? – Trufa

2

Para un hash decente, el atacante no invertirá el hash, usarán una tabla rainbow, que es esencialmente un método de fuerza bruta útil si todos usan la misma función hash.

La idea de una tabla de arcoiris es que, dado que el hash es rápido, puedo usar todos los valores posibles que pueda usar como contraseña, almacenar el resultado y tener un mapa de qué hash se conecta a cada contraseña. ¡Si todos solo toman sus contraseñas y las mezclan con MD5, entonces mi tabla hash es buena para cualquier conjunto de hashes de contraseñas que pueda tener en mis manos!

Aquí es donde entra la salazón. Si tomo la contraseña que el usuario ingresa y agrego algunos datos que son diferentes para cada usuario, entonces esa lista de hashes predeterminados es inútil ya que el hash es tanto de la contraseña como de algunos datos aleatorios. Los datos para la sal se pueden almacenar junto a la contraseña e incluso si obtengo ambos no me ayuda a recuperar la contraseña, ya que todavía tengo que forzar básicamente el hash por separado para cada usuario individual. No puedo formar un una sola tabla de arcoiris para atacar todos los hashes a la vez.

Por supuesto, idealmente un atacante no obtendrá la lista de contraseñas hash en primer lugar, pero algunos empleados tendrán acceso, por lo que no es posible proteger la base de datos de contraseñas por completo.

+0

si usa 'password' +' salt' obtiene 'hash', si su tabla rainbow es lo suficientemente grande, tendrá 'passAsaltA' y tal vez' passBsaltB' como coincidencias para ese 'hash', ahora tiene alguna idea sobre qué la contraseña tal vez si el sitio utiliza el mismo tiene para todos, podrá verlo presente en todos los resultados del partido. El verdadero problema es que tu mesa de arcoiris es lo suficientemente grande. –

+0

Es por eso que mencioné que la sal debería ser diferente para cada usuario. En el caso de que salte la contraseña directamente, la sal también debe tener una longitud y una complejidad mayores que la contraseña promedio, para evitar que la tabla arco iris estándar pase a pass + salt. Probablemente sea mejor cifrar la contraseña, agregar sal al hash, luego volver a generar y almacenar el resultado. – tloach

0

Esta es mi pregunta acerca de los aspectos de la colisión MD5, ligeramente relacionada con su pregunta:

Is there any difference between md5 and sha1 in this situation?

La parte importante es en las 3 primeras filas, es decir: que debe poner su sal antes de la contraseña, si desea lograr una protección más sólida, no después de.

+0

para ser sincero, no pude entender completamente qué está sucediendo allí :) ¡pero seguiré su consejo! – Trufa

1

Esa documentación es engañosa: enseña un concepto "vulnerable" y lo presenta de alguna manera como "seguro" porque (la contraseña guardada) parece un galimatías. Solo basura de Internet que no morirá. El siguiente enlace debería aclarar las cosas (aunque ya encontraste una buena parte). Buen trabajo.

Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes habla de MD5 (y por qué no debería usarse) junto con la sal (por ejemplo, cómo frustrar los ataques de arco iris) y proporciona información útil (como "Usar el sistema de contraseñas de otra persona. No construyas el tuyo"). Es una descripción general bastante buena.

+0

+1 para compartir un ejemplo, ¡gracias! Voy a echarle un vistazo! Encontré este http://tinsology.net/2009/06/creating-a-secure-login-system-the-right-way/ que parece prometedor también, supongo, todavía no he encontrado el tiempo. ¡¡Gracias de nuevo!! – Trufa

0

Para responder simplemente el título de su pregunta, el único uso real de md5 hoy en día es utilizar cadenas de gran tamaño (como archivos) para generar sumas de comprobación. Estos se suelen utilizar para ver si ambas cadenas son idénticas (en términos de archivos, las sumas de comprobación se utilizan con frecuencia por razones de seguridad para garantizar que un archivo distribuido no haya sido manipulado, por ejemplo).

Para hacer frente a cada una de sus preguntas en línea:

¿Cómo funciona el cifrado de la contraseña? ¿Cómo debería aplicar la encriptación de contraseñas para que sea realmente útil?

contraseña segura hash funciona tomando la contraseña en texto sin formato, y después aplicar una función hash costosa a ella, salados con una sal aleatoria segura mediante cifrado a ella. Consulte la pregunta Secure hash and salt for PHP passwords para obtener más detalles al respecto.

¿Qué tal esta idea?

El hash de la contraseña no necesita ser complicado así, y tampoco debería ser así. Evite pensar en sus propios algoritmos y seguir con los algoritmos de hash probados y comprobados que ya existen. Como la pregunta vinculada anteriormente menciona, md5() para el hash de contraseñas ha quedado obsoleto durante muchos años, por lo que debe evitarse.

Su método de generar una sal "aleatoria" a partir de una matriz de tres sales diferentes no es la aleatoriedad que está buscando. Necesita una aleatoriedad única que sea adecuada para seguridad criptográfica (es decir, utilizando un generador de números pseudoaleatorios crípticamente seguro (CSPRNG)). Si está utilizando PHP 7 y superior, entonces la función random_bytes se puede utilizar para generar una sal criptográficamente segura (para usuarios de PHP 5, se puede usar la biblioteca random_compat).