¿Por qué deben compararse las contraseñas por medio de una matriz de bytes?

4

Una mejor práctica en el proceso de inicio de sesión de una aplicación web es comparar las contraseñas con hash como matrices de bytes. ¿Cuál es la verdadera razón de esta mejor práctica? ¿Se trata de integridad?

Cert Secure Coding habla sobre el uso de matrices de bytes porque son más fáciles de liberar.

    
pregunta hmrojas.p 31.10.2017 - 19:17
fuente

2 respuestas

16

Hay un par de problemas en juego aquí. El primero, al que se hace referencia tanto en El ejemplo de Cert Secure Coding que vinculó y la respuesta StackOverflow del comentario de Daniel Grover no tiene nada específicamente para haga con la comparación del hash de una contraseña enviada por el usuario con un hash previamente almacenado, pero con el almacenamiento de la propia contraseña de entrada. El problema que describen es uno de la inmutabilidad de la cadena en plataformas como Java y .NET, lo que significa que si la contraseña de texto simple se almacena como una cadena, la aplicación no puede eliminarla, sino solo el recolector de basura, por lo que el volcado de memoria que se produce antes de que eso ocurra puede llevar a la exposición de una contraseña de texto simple.

Esto, sin embargo, no es realmente un problema al comparar hashes de contraseña. Las razones para usar matrices de bytes en lugar de cadenas tienen menos implicaciones de seguridad, pero sigue siendo una buena idea. Primero, porque la entrada y salida de una función hash generalmente tiene la forma de bytes. Si coloca bytes y obtiene bytes, la conversión a una cadena para comparar no tiene mucho sentido. Además, elimina una clase completa de errores (que podrían incluir vulnerabilidades de seguridad) causados por una codificación de cadena incorrecta. Por ejemplo, las matrices de dos bytes que representan dos contraseñas completamente diferentes pueden reportarse falsamente como idénticas si se convierten incorrectamente a ASCII antes de la comparación, porque en muchos casos, los bytes fuera del rango ASCII de 128 caracteres se convertirán al mismo valor de carácter ASCII (3F), abriendo el potencial para colisiones de cadenas incluso cuando las matrices de bytes originales no lo hicieron. Si deja los bytes solos, elimina esta vulnerabilidad potencial por completo.

Entonces, pensando en ellos y trabajando con ellos como lo que son, una salida de bytes de hash en lugar de cadenas conduce a un código más simple, más correcto y menos propenso a errores. Por seguridad, esto es algo bueno.

    
respondido por el Xander 31.10.2017 - 20:39
fuente
8

Estás confundiendo dos problemas ligeramente ortogonales aquí con la frase "comparar contraseñas con hash"

Almacenamiento de la contraseña (antes del hashing)

Como dice Jon Skeet en SO:

  

Las cadenas son inmutables (en Java y muchos otros lenguajes GC). Eso significa que una vez que haya creado la Cadena, si otro proceso puede volcar la memoria, no hay forma (aparte de la reflexión) que pueda deshacerse de los datos antes de que comience la recolección de basura.

Si está manejando la contraseña de un usuario, desea protegerse contra este riesgo, por lo tanto, utiliza un tipo de datos que puede sobrescribir inmediatamente una vez que lo haya usado; una matriz de bytes se ajusta perfectamente a la factura. Una vez que haya aplicado el algoritmo de hash de su contraseña, puede rellenar con cero la matriz (o utilizar datos aleatorios, o lo que sea).

Comparando los hashes (es decir, después del hashing, antes de iniciar sesión)

Bytes de salida de funciones hash. Es cómo se definen y, típicamente, cómo funcionan en la mayoría de los lenguajes de programación, por lo tanto, tiene más sentido simplemente comparar los dos bytestrings tal como son, sin ejecutarlos primero a través de ningún convertidor.

Sin embargo, si el hash de su contraseña está codificado en base64 en su base de datos, no hay pérdida de seguridad al tomar el hash de contraseña calculado y codificarlo en base64 y luego comparar cadenas. El hash ya está en su base de datos: si un atacante tiene acceso a su sistema suficiente para volcar la memoria del proceso, no debería ser muy difícil recuperar el hash de la contraseña de su base de datos, realmente no importa si lo eliminan. allí o desde una copia inmutable guardada hasta que su GC se ejecute.

Summary

Así que para mantener las cosas simples:

  1. Procese las contraseñas de los usuarios como matrices de bytes, sin utilizar tipos de cadena.
  2. Los hashes de proceso también como cadenas de bytes, ya que no hay ningún beneficio en convertirlos solo para comparar.
  3. Utilice un esquema de hashing de contraseña seguro. Argon2, si está disponible actualmente, se recomienda, de lo contrario, siga los consejos aquí: enlace
respondido por el diagprov 31.10.2017 - 20:37
fuente

Lea otras preguntas en las etiquetas