Red de conocimiento informático - Problemas con los teléfonos móviles - web.py Cómo pasar contraseñas de forma segura

web.py Cómo pasar contraseñas de forma segura

La mejor manera de proteger sus contraseñas es utilizar hash de contraseña salados. El hash de contraseñas es algo sencillo, pero es un error que mucha gente comete. A continuación, espero entrar en más detalles sobre cómo aplicar hash a las contraseñas correctamente y por qué debería hacerlo.

Importante

Si planea escribir su propio código para realizar hash de contraseñas, deténgase ahora. Es fácil cometer un error al hacer esto. Este recordatorio se aplica a todos: ¡no escriba su propio algoritmo de hash de contraseña! Una solución comprobada al problema de guardar contraseñas es utilizar phpass o el código fuente proporcionado en este artículo.

Qué es un algoritmo hash

Hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

Hash("hbllo") = 58756879c05c68dfac9 712fad6a93f8146f337a69afe7dd238f3364946366

hash("vals") = c0e81794384491161f1777c232bc6bd9ec38f616560b120fda8e90f383853542

El algoritmo hash es una función unidireccional. Función unidireccional. Puede convertir cualquier cantidad de datos en una "huella digital" de longitud fija, un proceso que es irreversible. Mientras los datos de entrada cambien, incluso si cambian un bit, el valor hash de salida será completamente diferente. Esta característica es excelente para contraseñas. Queremos cifrar la contraseña guardada utilizando un algoritmo irreversible, pero al mismo tiempo necesitamos verificar la exactitud de la contraseña cuando el usuario inicia sesión.

En un sistema de cuentas que utiliza algoritmo hash, el proceso general de registro de usuario y verificación de identidad es el siguiente:

1. El usuario crea la cuenta

2. contraseña Se almacena en la base de datos después de una operación hash. Las contraseñas sin texto claro se almacenan en el disco duro del servidor.

3. Cuando el usuario inicia sesión, compare la contraseña ingresada por el usuario con el valor hash de la contraseña almacenada en la base de datos después del hash.

4. Si los valores hash son exactamente iguales, la contraseña ingresada por el usuario se considera correcta. En caso contrario, se considerará que el usuario ha introducido una contraseña no válida.

5. Repetir los pasos 3 y 4 cada vez que el usuario intente iniciar sesión.

En el paso 4, no le digas al usuario si la cuenta o la contraseña son incorrectas. Simplemente muestre un mensaje genérico de que la cuenta o contraseña es incorrecta. Esto evitará que un atacante enumere nombres de usuario válidos.

También es importante tener en cuenta que la función hash utilizada para proteger la contraseña no es exactamente la misma que la función hash que se ve en la clase de estructura de datos. Por ejemplo, las funciones hash que implementan tablas hash están diseñadas para ser rápidas, pero no lo suficientemente seguras. Solo se pueden utilizar funciones hash criptográficas para el hash de contraseñas, como SHA256, SHA512, RipeMD, WHIRLPOOL, etc.

Un concepto común es que las contraseñas son seguras sólo después de haber sido codificadas. Obviamente esto es incorrecto. Hay muchas formas de recuperar rápidamente contraseñas de texto sin cifrar a partir de hashes. ¿Recuerdas esos sitios web para crackear md5? En estos sitios, simplemente envía el hash y conoce el resultado en menos de un segundo. Obviamente, el simple hecho de cifrar contraseñas está lejos de satisfacer nuestras necesidades de seguridad. La siguiente sección analizará primero los métodos comunes para descifrar hashes de contraseñas y obtener texto claro.

Cómo descifrar un hash

Diccionario y ataques de fuerza bruta

La forma más común de descifrar un hash es adivinar la contraseña. Luego se procesan todas las contraseñas posibles, el hash que se va a descifrar se compara con el hash de la contraseña adivinada y, si ambos valores son iguales, la contraseña adivinada previamente es la contraseña de texto sin formato correcta. Los ataques comunes para adivinar contraseñas incluyen ataques de diccionario y ataques de fuerza bruta.

Ataque de diccionario

Probé con Apple: falló

Probé con Blueberry: falló

Probé con Justinbeiber: falló

. ..

Prueba letmein: fallido

Prueba s3cr3t: ¡Éxito!

Los ataques de diccionario implican colocar contraseñas, palabras, frases y otras cadenas comunes que pueden usarse en contraseñas en un archivo, luego codificar cada palabra en el archivo y convertir estos hashes en comparación con el hash de contraseña que necesita estar agrietado. La tasa de éxito de este método depende del tamaño del diccionario de contraseñas y de si el diccionario es adecuado.

Ataque de fuerza bruta

Pruebe aaaa: fallido

Pruebe aaab: fallido

Pruebe aaac: falló

..

Pruebe acdb: falló

Pruebe acdc: ¡éxito!

Un ataque de fuerza bruta consiste en probar todas las combinaciones posibles de caracteres para una longitud de contraseña determinada. Este método requiere mucho tiempo de computadora. Pero en teoría, con el tiempo suficiente, la contraseña eventualmente será descifrada. Sin embargo, si la contraseña es demasiado larga, el tiempo necesario para descifrarla será demasiado largo e insoportable.

No hay forma de prevenir ataques de diccionario y ataques de fuerza bruta. Sólo hay una manera de hacerlos ineficientes. Si su sistema de hash de contraseñas está diseñado para ser muy seguro, la única forma de descifrar el hash es realizar un ataque de diccionario o un ataque de fuerza bruta.

Tablas de búsqueda

Las tablas de búsqueda son una forma muy eficiente y rápida de descifrar una gran cantidad de hashes de un tipo de hash específico. El principio es calcular previamente el valor hash de cada contraseña en el diccionario de contraseñas y luego almacenar el valor hash y la contraseña correspondiente en una tabla. Una estructura de tabla de búsqueda bien diseñada aún puede buscar cientos o miles de hashes por segundo, incluso si se almacenan miles de millones de hashes.

Si desea descifrar un hash a través de una tabla de búsqueda, puede intentar descifrar los siguientes hashes sha256 en CraskStation.

c11083b4b0a7743af748c85d343dfee9fbb8b2576c05f3a7f0d632b0926aadfc

08eac03b80adc33dc7d8fbe44b7c7b05d3a2c511166bdb43fcb7 03ba919e7

e4ba5cbd251c98e6cd1c23f126a3b81d8d8328abc95387229850952b3ef9f904

5206b8b8a996cf5320cb12ca91c7b790fba9f0304 83548dc3007bd

Tablas de búsqueda inversa

Buscando hash(apple) en la lista hash de los usuarios...: coincide con [alice3, 0bob0, charles8]

Buscar hash(blueberry) en la lista hash del usuario...: coincide con [usr10101, timmy , john91]

Busca en la lista hash del usuario hash(letmein)... : coincide con [wilson10, dragonslayerX, joe1984]

Busca en la lista hash del usuario hash (s3cr3t). ..: Coincidencias [bruce19, knuth1337, john87]

Buscar hash en la lista hash del usuario (z@29hjja)...: Ningún usuario ha utilizado esta contraseña

Buscar el hash (z@29hjja)... : Ningún usuario ha usado nunca esta contraseña en la lista hash del usuario

Este enfoque permite al atacante hacer esto sin precalcular la tabla de búsqueda Realizar ataques de diccionario y ataques de fuerza bruta en grandes cantidades de hashes.

Primero, el atacante crea una tabla de nombres de usuario y valores hash correspondientes en función de los datos de la base de datos obtenidos. Luego, después de analizar un diccionario de contraseñas comunes y compararlas con los hashes de esa tabla, podrá saber qué usuarios usaron esa contraseña. Este ataque es muy efectivo porque muchos usuarios suelen tener la misma contraseña.

Mesa Rainbow

La mesa Rainbow es una tecnología que intercambia espacio por tiempo. Es muy similar al descifrado de la tabla de búsqueda. Simplemente sacrifica algo de tiempo de descifrado para lograr el propósito de reducir el espacio de almacenamiento.

En la siguiente sección, discutiremos una técnica llamada "salado".

En la siguiente sección, discutiremos una técnica llamada "salado". Esta técnica hace que los hashes sean irrompibles en tablas de búsqueda y tablas de arcoíris.

Agregar sal

hash("hola") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824

hash("hola"+ "QxLUF1bgIAdeQX") = 9e20904 3f84a31e719795b2577523954739fe5ed3b58a75cff2127075ed1

hash("hola" + "bv5PehSMfV11Cd") =d1d3ec2e6f20fd420d50e2642992841d8338a314b8ea157c9e18477aaef226ab

hash("hola" + "YYLmfY6IehjZMQ") = a49670c3 b9e079b9cfaf51634f563dc8ae3070db2c4a8544305df1b60f007

La razón por la que los métodos de tabla de búsqueda y tabla arcoíris El trabajo es porque el hash de cada contraseña es el mismo. Si dos usuarios usan la misma contraseña, sus hashes de contraseña deben ser los mismos. Podemos evitar este ataque aplicando hash a la misma contraseña dos veces y obteniendo hashes diferentes aleatorizando cada valor hash.

Esto se hace agregando un prefijo o sufijo aleatorio a la contraseña y luego aplicando hash. Como se muestra en el ejemplo anterior, al agregar una sal, la misma contraseña será una cadena completamente diferente cada vez que se aplique el hash. Verificar que la contraseña ingresada por el usuario sea correcta también requiere un salt, por lo que el salt generalmente se almacena en la base de datos junto con el hash o como parte de la cadena hash.

No es necesario mantener la sal en secreto, las comprobaciones de las tablas y las tablas de arcoíris fallarán siempre que la sal sea aleatoria. Dado que el atacante no puede saber de antemano cuál será el valor de la sal, las tablas de búsqueda y las tablas de arco iris no se pueden calcular previamente. Un ataque de tabla de búsqueda inversa también fallará si cada usuario usa una sal diferente.

En la siguiente sección, veremos algunas implementaciones incorrectas comunes de sales.

El enfoque incorrecto: sales cortas y reutilización de sales

Los errores de implementación más comunes son usar una sal en múltiples hashes o usar una sal muy corta.

Reutilización de sales

Usar la misma sal en cada hash de contraseña anula esta defensa, ya sea que las sales estén codificadas en el programa o se generen aleatoriamente una a la vez. Esto se debe a que aplicar hash a la misma contraseña dos veces dará el mismo resultado. Esto permite a los atacantes aprovechar la tabla de búsqueda inversa para ataques de diccionario y de fuerza bruta. Simplemente agregue esta sal fija antes de codificar cada contraseña en el diccionario.

Los usuarios deben utilizar un nuevo salt aleatorio cada vez que crean o cambian una contraseña

Short salt

Si el salt es demasiado corto en dígitos, el atacante puede todavía se puede preparar previamente una tabla de búsqueda para todas las sales posibles. Por ejemplo, un carácter ASCII de 3 bits **** tiene 95x95x95 = 857,375 posibilidades. Esto parece un número grande. Si crea una tabla de búsqueda de 1 MB de contraseñas comunes para cada sal, 857,375 sales son 837 GB.

Por la misma razón, nunca uses el nombre de usuario como sal.

Si bien el nombre de usuario de cada usuario puede ser diferente, son predecibles y no completamente aleatorios. Los atacantes pueden usar nombres de usuario comunes como sales para crear tablas de búsqueda y tablas de arcoíris para descifrar funciones hash.

Una regla basada en cierta experiencia es que el tamaño de la sal debe coincidir con la salida de la función hash. Por ejemplo, la salida de SHA256 es de 256 bits (32 bytes), entonces la longitud del salt también debe ser de 32 bytes de datos aleatorios.

El enfoque equivocado: doble hash y funciones hash extrañas

Esta sección analiza otro error común sobre el hash de contraseñas: combinaciones extrañas de algoritmos hash. Se podría pensar que combinar diferentes funciones hash haría que los datos sean más seguros. Pero en la práctica, este enfoque tiene poco efecto. En cambio, puede causar algunos problemas de interoperabilidad y, a veces, incluso hacer que los algoritmos hash sean menos seguros. Como se mencionó al principio de este artículo, nunca intente escribir su propio algoritmo hash; en su lugar, utilice algoritmos estándar diseñados por expertos. Algunos pueden argumentar que el uso de múltiples funciones hash hace que sea más difícil descifrar al ralentizar los cálculos hash. Hay mejores formas de defenderse de los ataques ralentizando los cálculos de hash, que se tratan con más detalle a continuación.

A continuación se muestran algunos ejemplos de combinaciones extrañas de funciones hash que se encuentran en línea.

md5(sha1(contraseña))

md5(md5(salt) + md5(contraseña))

sha1(sha1(contraseña))

sha1(str_rot13(contraseña + salt))

md5(sha1(md5(md5(contraseña) + sha1(contraseña)) + md5(contraseña)))

¡No usar!

Nota: ¡Esta parte es realmente controvertida! Recibo toneladas de correos electrónicos que dicen que combinar funciones hash tiene sentido. Porque si el atacante no sabe qué función usamos, es imposible calcular la tabla del arco iris de antemano y combinar funciones hash requiere más tiempo de cálculo.

Naturalmente, si el atacante no conoce el algoritmo de hash, no podrá descifrarlo. Pero dado el principio de Kerckhoff, los atacantes a menudo tienen acceso al código fuente (especialmente al software gratuito y de código abierto). No es muy difícil aplicar ingeniería inversa al algoritmo a través de algunas correspondencias de hash de contraseña en el sistema de destino.

Si desea utilizar una función hash estándar "peculiar" (como HMAC), no hay problema. Pero si su objetivo es ralentizar los cálculos hash, lea el capítulo sobre funciones hash lentas que se analiza más adelante. Según los factores anteriores, la mejor práctica es utilizar algoritmos hash estándar y rigurosamente probados.

Colisión de hash

Dado que una función hash asigna cualquier cantidad de datos a una cadena de longitud fija, es seguro que diferentes entradas se convertirán en la misma cadena después de la situación de hash. Las funciones hash criptográficas están diseñadas para hacer que estos ataques de colisión sean prohibitivamente costosos de implementar. Sin embargo, de vez en cuando los criptógrafos encuentran formas de implementar rápidamente colisiones hash. Un ejemplo reciente es MD5, que ha implementado ataques de colisión.

El propósito del ataque de colisión es encontrar otra cadena que no sea la misma que la contraseña original pero que tenga el mismo valor hash. Sin embargo, incluso los algoritmos hash relativamente débiles (como MD5) requieren una gran cantidad de potencia informática para implementar ataques de colisión, por lo que la posibilidad de que se produzcan accidentalmente colisiones hash en aplicaciones prácticas es muy pequeña. El hash de contraseñas que utiliza el algoritmo MD5 salado es en realidad tan seguro como otros algoritmos como SHA256. Sin embargo, si es posible, es mejor utilizar funciones hash más seguras como SHA256, SHA512, RipeMD, WHIRLPOOL, etc.

La forma correcta: cómo realizar hash correctamente

Esta sección analiza en detalle cómo realizar hash criptográficamente correctamente. La siguiente sección explica cómo seguir mejorando la seguridad y hacer que el descifrado de hash sea extremadamente difícil.

Conceptos básicos: uso de salted hashes

Ya sabemos que los piratas informáticos malintencionados pueden obtener rápidamente la contraseña en texto plano correspondiente al hash a través de tablas de búsqueda y tablas de arcoíris, y también lo sabemos a través de Use sal al azar para resolver este problema.

Pero, ¿cómo generamos la sal y cómo la usamos en el proceso de hashing?

El salt se genera utilizando un generador de números pseudoaleatorios criptográficamente seguro (CSPRNG), que es distinto de los generadores de números pseudoaleatorios ordinarios como C rand(). Como sugiere el nombre, CSPRNG proporciona un alto estándar de números aleatorios que son completamente impredecibles. No queremos que nuestra sal sea predecible, así que asegúrese de usar CSPRNG.