| Artículos | 01 MAY 2007

Contraseñas, Hashes y números aleatorios

Tags: Histórico
Curso de criptografía para la Web (IV)
Gonzalo Alvarez.
Esta entrega explica numerosos usos de los algoritmos de hash y cómo implantarlos en aplicaciones web. También se destaca la importancia de la correcta generación de números aleatorios, y cómo conseguirlo mediante los lenguajes más usados en el desarrollo web.

Nivel de dificultad: Bajo
Objetivo: Implantar de forma segura los hashes y la generación de números aleatorios en una aplicación web
Herramientas: Las propias herramientas de desarrollo de aplicaciones web

Hashes
Las funciones de resumen, o hash para abreviar, se utilizan para producir un resumen de longitud fija a partir de un mensaje de longitud variable, siendo la longitud del resumen muy inferior a la del mensaje, entre 128 y 512 bits, típicamente.
El concepto de hash le resultará familiar a muchos programadores, en relación a las tablas o mapas de hash. Así representan una colección de pares de clave y valor organizados en función del código de la clave. Sin embargo, los hashes usados en criptografía se caracterizan porque resulta imposible regenerar el mensaje conociendo sólo el resumen u obtener cualquier información acerca del mensaje original, lo que se conoce como propiedad de unidireccionalidad. Poseen además una tasa de colisiones muy baja, es decir, la probabilidad de que a partir de dos mensajes distintos se obtenga el mismo hash es muy baja. Suponiendo que la longitud del hash es de n bits, entonces la probabilidad de que dos textos distintos generen el mismo hash será igual a 2-n. El motivo detrás de la utilización de los hashes es que estos sirvan a modo de huella o resumen compacto de un mensaje mediante una cadena de bits de menor longitud, de manera que esta cadena pueda servir para identificar unívocamente al mensaje original.
Su utilidad más importante se presenta a la hora de proporcionar integridad de datos, ya que si se cambia un bit del mensaje, cambia por completo el resumen, es decir, el 50 por ciento de sus bits. Por ejemplo, en el contexto de las firmas digitales, lo que se hace es calcular previamente un hash del mensaje a firmar a modo de representación compacta del mensaje y firmar posteriormente el hash en lugar del mensaje original.
En este artículo no se entrará en más detalles criptográficos acerca de los hashes más allá de las propiedades mencionadas. Existen numerosos algoritmos de hash en la actualidad, entre los cuales los indudablemente más utilizados para resúmenes criptográficos son MD5 y SHA-1. No obstante, MD5 se considera inseguro hoy día (véase el recuadro ¿Es MD5 seguro?) y se están descubriendo debilidades en SHA-1, por lo que se recomendamos abandonar su uso y recurrir mejor a SHA256 ó SHA512.
Uno de los usos más importantes de los hashes en una aplicación que trabaja con usuarios autenticados mediante nombre y contraseña consiste en almacenar el hash de la contraseña, nunca jamás la contraseña en claro. No importa si como almacén de credenciales se utiliza una tabla en una base de datos, un archivo XML o un archivo de simple texto; la contraseña no debería almacenarse en claro, ya que si un atacante obtuviera acceso al repositorio de contraseñas podría recuperarlas todas inmediatamente. Para evitar esta fácil violación de la confidencialidad, la mejor defensa consiste en almacenar, no la contraseña directamente, sino su hash. En adelante, aunque un atacante se hiciese con la información del almacén, no podría conocer directamente las contraseñas. Su único recurso consistiría en la utilización de una herramienta de cracking de contraseñas para tratar de obtenerlas mediante ataques de fuerza bruta, de diccionario o una combinación de ambos.
En los ataques de fuerza bruta se van probando todas las posibles combinaciones de letras y números. Seguro que tiene, o ha visto, una de esas maletas protegidas por un cierre con combinación, introducida típicamente con tres ruedecillas con 10 dígitos cada una. Si olvidase la combinación de su maleta, tendría que probar todas las combinaciones posibles, que en este caso se reducen a 103 = 1.000, lo que significa que, en promedio, habría que probar 500 combinaciones hasta dar con la buena. Volviendo a las contraseñas, supóngase que la longitud máxima de la contraseña es de 8 caracteres alfanuméricos: habrá un total de 358 = 2.251.875.390.625 = 241 combinaciones posibles que probar. Aunque a simple vista puede parecer una cantidad formidable, en la práctica no lo es tanto, ni siquiera para un ordenador de capacidad modesta. De ahí la importancia en una buena gestión de contraseñas de obligar a los usuarios a elegir contraseñas de mayor longitud, por ejemplo, 12 caracteres mínimo, distinguir mayúsculas y minúsculas, e incluir caracteres no alfanuméricos. En este caso, el número de posibles contraseñas a probar puede ser tan fabuloso que disuade a un atacante de utilizar ataques de fuerza bruta.
Por desgracia, no acaban ahí los problemas: los usuarios, como humanos que son, intentan elegir contraseñas fáciles de recordar, lo que a menudo significa que escogen palabras que aparecen listadas en un diccionario. Aquí es donde entran en juego los ataques de diccionario. En este caso, no se prueban sistemáticamente combinaciones arbitrarias de letras, sino aquellas palabras que aparecen compiladas en enormes diccionarios disponibles en Internet. En www.word-list.com se pueden descargar en varios idiomas. Por supuesto, hay otros muchos sitios donde descargar diccionarios y listas de palabras utilizadas frecuentemente como contraseña. De esta forma se puede acelerar considerablemente el ataque.
Por último, muchas herramientas de cracking de contraseñas, como Cain & Abel, mostrada en la Figura 2, no se limitan a realizar ataques puramente de fuerza bruta o de diccionario, sino que también utilizan combinaciones de ambos: por ejemplo, se toman palabras de un diccionario y se realizan algunas transformaciones sobre ellas, se les añaden dígitos, etc.
Obviamente, para cada contraseña que se desea probar hay que calcular previamente el hash para poder compararlo con el almacenado en el repositorio de contraseñas. Imagínese que el ataque se repite para distintos usuarios. En este caso, se estaría calculando una y otra vez el hash de las mismas contraseñas. Aunque calcular un hash es un proceso rápido, repetirlo millones de millones de veces hace que el ataque se ralentice. Por este motivo, existe la posibilidad de realizar cracking utilizando los hashes precalculados de las contraseñas a probar, lo que acelera notablemente el ataque.
Con el fin de evitar este tipo de aceleración del ataque pueden utilizarse los salt. Un salt es un número aleatorio que se añade a la contraseña para calcular el hash del conjunto. Los salt no se mantienen en secreto, sino que se almacenan en claro junto al nombre de usuario y el hash del salt más la contraseña. Ahora, ya no sirve de nada tener precalculados los hashes de contraseñas, porque se ha calculado el hash de la contraseña más el salt. Este mecanismo se utiliza por ejemplo en los archivos passwd de almacenamiento de contraseñas de Unix, y por supuesto puede ser añadido a cualquier esquema de autenticación de usuarios desarrollado para una aplicación web. Otras ventajas del uso de salts es que si dos o más usuarios han elegido la misma contraseña, el hash será distinto, al haberse añad

Contenidos recomendados...

Comentar
Para comentar, es necesario iniciar sesión
Se muestran 0 comentarios
X

Uso de cookies

Esta web utiliza cookies técnicas, de personalización y análisis, propias y de terceros, para facilitarle la navegación de forma anónima y analizar estadísticas del uso de la web. Consideramos que si continúa navegando, acepta su uso. Obtener más información