Hashing de contraseña

Feb 08 2023
La superficie de ataque de las contraseñas
Algunos de los ataques de seguridad cibernética más devastadores surgen de violaciones de contraseñas, que se almacenan de manera deficiente en las bases de datos del lado del servidor. El problema podría comenzar con el usuario, que puede estar inclinado a establecer una contraseña básica y fácil de recordar.
Foto de Michael Dziedzic en Unsplash

Algunos de los ataques de seguridad cibernética más devastadores surgen de violaciones de contraseñas, que se almacenan de manera deficiente en las bases de datos del lado del servidor.

El problema podría comenzar con el usuario, que puede estar inclinado a establecer una contraseña básica y fácil de recordar. Esto produce un riesgo, ya que los atacantes pueden adivinarlo fácilmente si tienen una comprensión contextual del individuo, como los nombres de mascotas o familiares.

Incluso cuando se elige una contraseña más complicada, el software de descifrado de contraseñas puede desencadenar un ataque de fuerza bruta, lo que resulta en una gran cantidad de contraseñas probadas hasta el éxito.

Otro vector de ataque es obtener acceso a la base de datos que almacena las credenciales. En el escenario de pesadilla de un CISO, si un atacante obtuviera acceso a una base de datos de contraseñas de texto sin formato sin cifrar, miles de cuentas de usuario podrían verse comprometidas de inmediato. Desafortunadamente, esto ha ocurrido con demasiada frecuencia, afectando a organizaciones tanto pequeñas como grandes.

¡No temas, estas perspectivas angustiosas pueden verse limitadas por algo llamado hash de contraseña!

Foto de Markus Spiske en Unsplash

Definición de hash

El hashing de contraseñas es una técnica algorítmica criptográfica que toma texto sin formato, ejecuta una función hash complicada y produce texto hash. La clave de este proceso es la función, pero no todas son igualmente adecuadas para evitar el agrietamiento.

Todas las funciones deben satisfacer dos propiedades clave para cumplir con los criterios de OWASP (Proyecto de seguridad de aplicaciones web de código abierto):

Es difícil crear una entrada inicial que corresponda a una salida específica deseada.

Para ilustrar esta característica, el hash de 'Contraseña' generado a través del popular algoritmo criptográfico sha256 es:

e7cf3ef4f17c3999a94f2c6f612e8a888e5b1026878e4e19398b23bd38ec221a

Y el hash de 'contraseña' es:

5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

Como puede ver, simplemente cambiando las mayúsculas de una letra de la entrada, se produce una salida significativamente diferente, lo que significa que las salidas no se pueden determinar fácilmente a partir de las entradas.

Es práctico producir el hash pero prácticamente imposible volver a generar la entrada si solo se conoce el valor del hash.

A diferencia del cifrado, donde una contraseña de texto sin formato se convierte en texto encriptado antes de descifrar de nuevo a texto sin formato, el hashing es una función de forma única. Como el hash de contraseña es determinista, la misma entrada siempre produce la misma salida.

El caso de uso de esto es cuando un usuario crea una contraseña, se puede codificar y luego la salida se almacena en una base de datos. Cuando el usuario vuelve a intentar su contraseña, se vuelve a codificar y luego se verifica con el hash en la base de datos. Si un atacante obtiene acceso a la base de datos hash, es en gran medida inútil, ya que las contraseñas no se pueden volver a convertir en texto sin formato.

Intente ejecutar este script de Python para ver una versión simple de este concepto :

# this and other fun scripts can be found at: https://github.com/Jay-Gokani

# install sha256 library for hashing
from hashlib import sha256

# demo explanation
print ('Hello, this demo will ask for a plaintext password, hash it and will verify the hash for access requests')

# first hash stored as a variable
hash1 = (sha256(input('What phony password would you like to set? ').encode('utf-8'))).hexdigest()
print('The hash of your plaintext password is:', hash1)

# password hash stored confirmation
print ('Your password hash has been successfully stored.')

# promt the user for password re-entry, hash and store as another variable
hash2 = (sha256(input('I will test your hash. Please type your password: ').encode('utf-8'))).hexdigest()
print('The hash of your plaintext password is:', hash2)

# access approval or deny check
while True:
    if hash1 == hash2:
        print('Success - password hash matches.')
        break
    else:
        print('The password hash does not match. Please run the programme again.')
        break

Los hashes, por supuesto, no son una solución todo en uno para evitar contraseñas comprometidas. Por ejemplo, los atacantes pueden producir listas de contraseñas comunes y sus hashes correspondientes. Si algún hash en la base de datos está en la lista, el atacante conocerá la contraseña de texto sin formato. Pero esto no debería ser un problema si las contraseñas de texto sin formato se crean con suficiente complejidad. Además, la aplicación que ingiere contraseñas en texto plano para producir hashes podría ser interceptada.

¡El hashing de contraseñas es un gran paso en la dirección correcta! Esperamos que hayas disfrutado este artículo :-)