Qué guarda una web cuando te registras
Una web nunca debe guardar tu contraseña tal cual. Debe guardar un hash con sal, calculado con una función lenta pensada para contraseñas.
Si una tienda online sufre un robo de datos, el atacante se lleva esa tabla. Con un buen hash no puede leer las contraseñas sin probarlas una a una.
Al final de esta lección
Nota
Puedo guardar contraseñas y claves de forma que un robo de datos no las revele.
Palabras clave
| Palabra | Qué significa | Ejemplo |
|---|---|---|
| Sal | un texto al azar que se mezcla con cada contraseña antes del hash | |
| Hash lento | un hash que cuesta tiempo a propósito, para frenar los intentos | PBKDF2 |
| Iteraciones | las veces que se repite el cálculo del hash | |
| Diccionario | una lista de contraseñas comunes que el atacante prueba primero | |
| Gestor de secretos | un servicio que guarda claves fuera del código | |
| Rotar una clave | cambiarla por otra nueva cada cierto tiempo |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Un hash solo no basta para una contraseña
Como el mismo texto da siempre el mismo hash, un atacante puede calcular de antemano los hashes de millones de contraseñas comunes. Si ve el mismo hash dos veces en tu tabla, sabe que dos personas usan la misma clave.
Mira el hash de una contraseña floja.
Calcula el hash simple de clave123
printf 'clave123' | sha256sumSe muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
La sal hace distinto cada hash
Una sal es un texto al azar, distinto para cada usuario, que se mezcla con la contraseña antes del hash. La sal no es secreta. Se guarda junto al hash.
Con sal, la misma contraseña da hashes distintos y los hashes calculados de antemano ya no sirven.
Hash de clave123 con la sal sal1
python3 -c "import hashlib; print(hashlib.pbkdf2_hmac('sha256', b'clave123', b'sal1', 1000).hex())"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
La misma contraseña con la sal sal2
python3 -c "import hashlib; print(hashlib.pbkdf2_hmac('sha256', b'clave123', b'sal2', 1000).hex())"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Un error frecuente
Advertencia
Mucha gente cree que cuanto más rápido es un hash, mejor. Para una huella de archivo sí. Para una contraseña es lo contrario: un hash rápido deja al atacante probar miles de millones de intentos por segundo.
Un hash lento frena a quien prueba contraseñas
Un hash para contraseñas se repite muchas veces, las iteraciones. Cada intento cuesta más, también para el atacante.
La tabla compara un hash rápido, mil millones de intentos por segundo, con uno lento, mil. Las cifras son órdenes de magnitud.
Ejemplo: probar todas las contraseñas de solo cifras
| Cifras | Posibilidades | Hash rápido | Hash lento |
|---|---|---|---|
| 4 | 10 mil | Al instante | 10 segundos |
| 6 | 1 millón | Un milisegundo | Unos 17 minutos |
| 8 | 100 millones | Una décima de segundo | Más de un día |
Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.
Calcula el coste de un ataque
# Cuánto tarda probar todas las contraseñas de solo cifras.
intentos_por_segundo = 1000 # un hash lento
cifras = 6
posibles = 10 ** cifras
segundos = posibles // intentos_por_segundo
print("Segundos:", segundos)
print("Minutos aproximados:", segundos // 60)
# Cambia cifras a 8 y pulsa Ejecutar. Después sube intentos_por_segundo a 1000000000.
Las claves nunca van escritas en el código
Una clave en el código acaba en el repositorio, y el repositorio lo ve mucha gente. Guárdala fuera: en una variable de entorno o en un gestor de secretos.
Usa claves distintas para cosas distintas. Rota cada clave cada cierto tiempo, y cámbiala al instante si crees que se ha filtrado. Genera claves con un generador seguro, no con tu cabeza.
Genera una clave y cuenta sus cifras
python3 -c "import secrets; print(len(secrets.token_hex(16)))"Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.
Para ir más lejos
Cambia las iteraciones de 1000 a 100000 en una de las órdenes con pbkdf2_hmac. Observa que la respuesta tarda más, y el hash cambia por completo.
Piensa cuántas iteraciones aguantaría tu servidor si mil personas inician sesión a la vez.