¿Mi algoritmo de hashing de contraseña personalizado es inseguro?

16

Para todos mis proyectos web de hobby, he codificado un sistema de inicio de sesión que estos proyectos comparten. No hay datos críticos en estos proyectos, los únicos datos críticos podrían ser contraseñas reutilizadas. Así que trato de cifrar las contraseñas de una manera muy segura.

Mi algoritmo de hashing de contraseña actual no es nada que pueda llamar realmente seguro. Y cuando vi que PHP ahora ofrece un hashing con password_hash , pensé en cambiar.

Mi pregunta es, ¿cuáles son los beneficios de cambiarme? En términos de, ¿qué protección adicional obtengo, qué orificio (s) reparo, etc.? ¿Y hay algo más que deba hacer para que no sea extremadamente inseguro?

Me gustaría usar las respuestas como una experiencia de aprendizaje para mí, para poder enseñárselas a otras personas que están en mi posición.

Mi algoritmo actual (pseudo-código):

Salt = "some-salt" 
Repeat 1000000 times
    Password = Sha512(Salt + username + Salt + Password) 

Sé que mi sitio es vulnerable a los ataques de tiempo y las funciones integradas de PHP lo arreglarían.

¿Qué más es obviamente inseguro?

    
pregunta Kostronor 12.09.2014 - 09:56
fuente

6 respuestas

33

Para empezar, usted lanzó su propio algoritmo de hashing de contraseñas. Actualmente hay solo tres algoritmos de hashing de contraseñas que se consideran seguros:

  • PBKDF2
  • scrypt
  • bcrypt

Estás iterando y estás agregando una sal. También parece que agrega el nombre de usuario dentro del algoritmo, que no agrega ningún beneficio ya que ya está usando un salt.

Lo que no puedo deducir de tu código y lo que es muy importante es la longitud de tu sal y cómo la generas. Una sal nunca se debe codificar, pero se debe generar de forma aleatoria y segura al incluir la contraseña. La sal debe ser única dentro de la base de datos y preferiblemente globalmente única para evitar la identificación de contraseñas similares en diferentes bases de datos (por lo tanto, un nombre de usuario no se considera una buena sal).

También la forma en que funciona PBKDF2 (que se inclina más cerca de su implementación) es mediante el uso de un HMAC, donde la sal generada aleatoriamente es la clave utilizada para calcular el resumen del mensaje, en lugar de agregar todo junto. El password_hash de PHP está usando el algoritmo bcrypt.

Entonces, para resumir lo que gana al usar un algoritmo estándar en lugar del suyo:

  • Generarás sales aleatorias
  • Utilizará un algoritmo de hashing de contraseña seguro y estandarizado
respondido por el Lucas Kauffman 12.09.2014 - 11:01
fuente
18

Suponiendo que some-salt en realidad nunca se repita, este es un método de hashing de contraseña aceptable. Combina los tres elementos esenciales: la recuperación del hash de las contraseñas (gracias al uso de SHA-512), la lentitud intrínseca (debido al alto número de iteraciones de SHA-512) y una sal única.

El salt debe ser globalmente único: no se debe utilizar para cifrar otras contraseñas, para modificar la misma contraseña en un cambio de contraseña o en la base de datos de contraseñas de otra persona. Violar la singularidad no es absolutamente crítico, pero cuanto más ocurra, más fácil será para un atacante. En el extremo del rango, la "sal" es constante, no es una sal y su método de hashing de contraseñas es horrible. Si es el nombre de usuario o el ID de registro, todavía es malo porque varias bases de datos compartirán un pequeño conjunto de sales.

No obstante, debe utilizar un método de hashing estándar. Puede haber una vulnerabilidad en su método que no vimos porque se basa en algunos detalles sutiles. Es posible que hayas cometido un error en la implementación; una implementación bien soportada con actualizaciones de seguridad es preferible por esta razón. Se puede descubrir una debilidad en el algoritmo; de nuevo, es mejor usar una implementación bien respaldada cuyo implementador esté al tanto de las noticias de criptografía y cambiará el algoritmo si es necesario.

Una cosa que debe tener en cuenta es aumentar el número de iteraciones a medida que pasa el tiempo y las computadoras se vuelven más rápidas. Un buen

Lea ¿Cómo hash seguro de contraseñas? (sí , todo ello). Bcrypt es algo superior a PBKDF2, porque es más resistente a los ataques basados en GPU; PBKDF2 sigue los mismos principios que su hash personalizado. El uso de PBKDF2 no es una vulnerabilidad importante en este momento, pero aún así recomendaría cambiar a bcrypt o scrypt.

    
respondido por el Gilles 12.09.2014 - 15:10
fuente
16

Su algoritmo es mejor por millas que muchos de "homebrew". La razón por la que todavía cambiaría a uno estandarizado es que obtienes el beneficio de todo el escrutinio que estas normas han recibido y que tu propia construcción no ha recibido.

¿Definitivamente no hay ningún error en tu construcción que permita una ruptura trivial? Si no es así, ¿estás seguro de que tu algoritmo no es vulnerable a un ataque de fuerza bruta acelerada utilizando GPU masivamente paralelas? ¿Podría haber una forma optimizada de ataque de tabla arco iris en su algoritmo particular?

La respuesta es probablemente no, no y no, pero más personas han visto PBKDF2 que su algoritmo, por lo que es menos probable que haya algo desagradable que nadie haya visto hasta ahora. Este es un argumento heurístico, pero no lo olvide, incluso si su algoritmo es bueno (y ciertamente no me parece estúpido), hay cientos de otras personas que han implementado su propio cifrado que resultó terriblemente roto. . Es por eso que, por regla general, decimos que no hagas tu propio rollo.

Es la misma razón por la que no permitimos que cualquiera instale y modifique conexiones eléctricas de alto voltaje: tener la calificación de un electricista no lo protege mágicamente de la electrocución, pero significa que probablemente tenga suficiente experiencia en el área No hagas nada demasiado estúpido como agarrar un cable al azar y ver si está activo o no.

    
respondido por el Bristol 12.09.2014 - 15:29
fuente
8

Un inconveniente de incluir el nombre de usuario como parte de Salt es que significa que no puede cambiar el nombre de un usuario (por ejemplo, administrativamente) sin generar un nuevo hash de contraseña (lo que significa que tendrá que elegir una nueva contraseña y decirle al usuario). pregunte al usuario por su contraseña actual).

    
respondido por el Andrew Medico 12.09.2014 - 18:47
fuente
3

En primer lugar, desde una perspectiva de seguridad de contraseña, tiene un algoritmo bastante bueno.

Técnicamente, su sal no es una sal, ya que es la misma para todos los usuarios, pero cuando la combina con el nombre de usuario es una pieza de información única, por lo tanto, tiene la seguridad completa de una sal. Si su cadena "some-salt" es criptográficamente fuerte (al menos 64 bits de entropía), también funciona como pimienta .

Desde un punto de vista práctico, generalmente querrá evitar incluir el nombre de usuario en el algoritmo hash de contraseña, ya que esto hace que sea complicado cambiar el nombre de usuario, y necesitará la contraseña de texto simple para la operación. Una sal dedicada es más fácil de manejar.

Un millón de iteraciones de hash parece un poco exagerado, podría convertirse fácilmente en el cuello de botella de un sitio web ocupado, lo escalaría de nuevo a un nivel en el que puedes hacer al menos 1000 hashes de contraseña por segundo.

También asegúrese de tener un mecanismo para acelerar los intentos de inicio de sesión, si un atacante puede simplemente grabar 1000 intentos de inicio de sesión por segundo, puede robar rápidamente muchas cuentas de usuario de contraseñas débiles, o puede usar el hashing de contraseñas como una denegación de Arma de servicio.

No creo que exista una mejor práctica ampliamente aceptada para la regulación de inicio de sesión, excepto que la limitación no es la peor solución posible.

    
respondido por el aaaaaaaaaaaa 13.09.2014 - 13:03
fuente
2

Puedo ver algunos problemas con tu enfoque.

  • Parece que estás usando un valor de sal constante. Es más seguro generar un nuevo salt para cada contraseña.
  • Incluir un nombre de usuario en la sal puede ser problemático. Como señaló Andrew, significa que no puede cambiar el nombre de un usuario. Mitiga parcialmente el problema con una sal constante. Pero no mitiga completamente el problema, porque el nombre de usuario no cambia cada vez que cambia la contraseña.
  • Solo incluye la contraseña en la primera iteración. Existe un riesgo teórico de que la entropía de la contraseña desaparezca lentamente a medida que se repite.
  • El alto recuento de iteraciones puede hacerlo vulnerable a los ataques DoS.

El recuento de iteraciones es un arma de doble filo. El alto recuento de iteraciones hace que su servidor sea vulnerable a los ataques DoS. El bajo recuento de iteraciones hace que su base de datos de contraseñas sea vulnerable a ataques de fuerza bruta sin conexión. La única forma de protegerse de ambos es descargar parte del cálculo al cliente. Pero esto requiere código en el cliente. En un servicio web, tal código podría ser entregado por javascript, pero javascript no es tan rápido como el código nativo, por lo que el atacante tendría una ventaja sobre el uso legítimo.

    
respondido por el kasperd 13.09.2014 - 10:48
fuente

Lea otras preguntas en las etiquetas