¿Cuál es el problema con la cadena de hash?

10

Digamos que mi contraseña es un solo carácter: "a".

¿No podría encadenar el hash 1000 veces (o más) y hacerlo casi invulnerable a los ataques de la mesa del arco iris y la fuerza bruta?

¿Por qué no se prefiere esto a la salazón y cuáles son los problemas con esta técnica, en su caso?

EDITAR: Aclaración: por cadena de hash me refiero a hashing the hash 1000 veces.

    
pregunta dee-see 31.01.2012 - 02:54
fuente

5 respuestas

19

Para reforzar un hash de contraseña, debes hacer dos al proceso de hash:

  1. para hacerlo único;
  2. para hacerlo lento.

"Único" significa que cada contraseña debe estar con su propia función hash; que se utiliza la función hash puede ser alguna información pública (es decir, almacenada a lo largo del valor de hash), pero desea hacerla diferente para cada contraseña que hash. Esto es lo que hace una sal : la sal define el procedimiento de hash a utilizar, entre una familia amplia. La singularidad derrota a las tablas de arco iris: las tablas de arco iris, al igual que todos los otros tipos de tablas precomputadas, se basan en la idea de que vale la pena dedicar un poco de tiempo a procesar muchas contraseñas y almacenar los valores de hash (posiblemente de una manera inteligente que permita cierta compresión extrema) , como las tablas arco iris), porque la tabla resultante se puede usar para atacar contraseñas de varias , con un costo marginal por contraseña muy pequeño. Con las sales, cada contraseña tiene su propia función, por lo que la tabla sería válida para, como máximo, una sola contraseña, lo que destruye sus ventajas.

Hashing "1000 (o más) veces" la contraseña no incluye un salt y, como tal, es vulnerable a las tablas precomputadas. Por ejemplo, asumiendo SHA-256 como función hash, aquí está su contraseña hash:

f3f19029aa4ef4bde723f49b4e90a7ad51473c54a03589af6fef706bf50d7894

Ese es el hash SHA-256 de 1000 'a' caracteres. Podría calcular este valor porque una vez que haya dicho "1000", lo habrá dicho todo; Sin sal, por lo tanto, no es una sorpresa para el atacante.

Lentitud trata de hacer que cada contraseña sea lo más cara posible para el atacante. Incluso con un buen uso de sal, una contraseña con hash individual puede ser vulnerable a la fuerza bruta, también conocida como " dictionary attack " (probar contraseñas potenciales), porque los humanos no son tan imaginativos como las computadoras son poderosos. Una PC con una GPU puede calcular una función hash un billón de veces por segundo aproximadamente. Queremos un procedimiento de hash que tarde más tiempo en calcularlo, no demasiado, porque nuestro servidor honesto también también tendrá contraseñas de hash cuando un usuario inicia sesión, y tampoco tenemos una CPU infinita; pero solo necesitamos un hash, como máximo, una docena de contraseñas por segundo, para poder tolerar una función de hash sustancialmente lenta.

Por lo general, la lentitud se obtiene mediante el hashing anidado: hash la contraseña, luego hash el valor hash resultante, que hash nuevamente, y así sucesivamente. Hay algunos detalles difíciles sobre cómo y dónde se inserta la sal. Hashing la concatenación de 1000 veces (en realidad, con las cifras anteriores, 1 millón de veces sería mejor) la contraseña (o la concatenación de la contraseña y la sal) podría servir al mismo propósito, pero es un poco delicado en la práctica: de hecho, queremos configurar el número de repeticiones de la contraseña para que el procedimiento sea tolerablemente lento. Pero con tal sistema, el hashing de una contraseña de 40 caracteres toma 40 veces más tiempo que el hashing de una contraseña de 1 carácter; si el último debe ser lento, el primero será 40 veces más lento, lo que pronto se volverá intolerable. Con el hashing anidado, es más fácil obtener un tiempo de hashing constante, lo que facilita la configuración.

Y, por supuesto, lo casero es malo . Insertar una contraseña y un salt en una función hash, iterada y / o anidada, es sutil; hay escollos y, lo que es peor, no puedes saber si lo hiciste mal o no. La seguridad no puede ser probada de manera confiable. Por lo tanto, debe atenerse a los estándares publicados y ampliamente implementados de buena reputación, como bcrypt y PBKDF2 . Solo porque eso significa que cualquier percance no será culpa de su .

    
respondido por el Tom Leek 31.01.2012 - 13:11
fuente
5

Fortalecimiento / estiramiento de las teclas es una buena técnica (aunque 1000 no te hace mucha gracia cuando solo hashes - md5 / sha1 se puede calcular a una velocidad de ~ 1 billón por segundo por gpu).

En aras de la simplicidad, les voy a dar un ejemplo concreto. Usted tiene una aplicación web y voy a asumir que el adversario malicioso logró acceder a su servidor. Esto podría ser un administrador que es secretamente malvado, alguien que irrumpió en su sala de servidores, un conserje que tiene llaves o un pirata informático aleatorio que logró usar algún exploit para entrar.

El adversario primero gestiona exportar los nombres de usuario almacenados y sus hashes de contraseñas de su base de datos. Luego miran el código de ejecución de su servidor web para ver cómo comprueba las contraseñas. Ve algo en la sección de autenticación del código de su servidor web que se ve así:

def check_password(username, password_to_check):
    if is_username_in_db(username):
        already_failed = False
        hash_from_db = get_password_hash_from_db(username)
    else:
        already_failed = True
        hash_from_db = get_password_hash_from_db('some_known_user')
    i = 0
    computed_hash = password_to_check
    while i < 1000:
        computed_hash = compute_sha1_hash(computed_hash)
        i += 1
    if strcmp(computed_hash, hash_from_db) and not already_failed:
        return True
    else:
        return False 
 # As an aside note a successful case takes the same amount of cpu time as a failing case, 
 # so timing attacks do not reveal that users exist; 
 # you should also make sure that 'strcmp' (string comparison) doesn't fail prematurely.

Los atacantes dicen aha! Las contraseñas en la base de datos se hash 1000 veces y sin sal. Luego generan hashes a una velocidad de mil millones por segundo (por lo que pueden verificar un millón de contraseñas en un segundo) con su gpu moderno. Entonces, en aproximadamente 1 día de tiempo de computación gpu, obtuvieron hashes para 86.4 mil millones de contraseñas (36 bits de entropía) y construyeron una tabla de arco iris en su disco duro de terabyte.

Luego, buscan todos los hashes en la tabla del arco iris y encuentran muchas coincidencias; ahora, con la contraseña de texto sin formato y el nombre de usuario, intentan acceder a otros servicios de aquellos usuarios donde pueden haber reutilizado las contraseñas. Si las contraseñas tuvieran una sal única, tendrían que generar una nueva tabla de arco iris para cada contraseña, lo que hará que el ataque de fuerza bruta sea mucho menos exitoso (por ejemplo, un día o más de tiempo de GPU para forzar la fuerza bruta de cada contraseña simple).

    
respondido por el dr jimbob 31.01.2012 - 23:59
fuente
1

Porque no es no invulnerable a la fuerza bruta. Para encontrar la contraseña en las líneas de 'a' hash mil veces, todo lo que tengo que hacer es probar 52000 hashes (o considerablemente menos si la contraseña es en realidad 'a' porque apenas comienzo al principio del alfabeto), que es terriblemente fácil de hacer.

    
respondido por el Steve 31.01.2012 - 04:01
fuente
1

Si es una palabra simple del diccionario, la función tendría que ser muy lenta para detener cualquier ataque no trivial. Todo programa decente va a probar primero las contraseñas populares / contraseñas cortas / patrones simples. Luego tienes todos los problemas precalculados que otros han mencionado anteriormente. Eche un vistazo al esquema FreeBSD MD5 como un ejemplo decente de cómo tomar un viejo MD5 de mierda y hacerlo bastante resistente al cracking.     

respondido por el Marcin 01.02.2012 - 03:31
fuente
1

El hash de cadena no te protege del uso de tablas de arco iris.

    
respondido por el Arjan Einbu 08.02.2012 - 13:40
fuente

Lea otras preguntas en las etiquetas