22 de Junio, 2013

Contraseñas fáciles de recordar

Ayer por la tarde estuve jugando con la idea de generar contraseñas siguiendo el esquema explicado por xkcd en Password Strength.

Básicamente, como comentaba por encima en mi anotación sobre KeePassX, durante mucho tiempo nos han contando qué tipos de contraseñas son buenas: no uses una palabra que esté en el diccionario, usa letras en mayúsculas, minúsculas, números y símbolos; y además que sea de longitud 8 o más.

Es decir, algo como lo que KeePassX sería perfecto para recordar (ponía de ejemplo WL?J$tW=c!m2N.`S), pero que resulta muy difícil para un ser humano :D.

Durante mucho tiempo he confiado en pwgen como buen generador de contraseñas recordables (pese a que por defecto no es completamente aleatorio, para que el resultado sea más fácil de memorizar), aunque resulta que no es tan bueno porque las contraseñas de pwgen tienen una distribución no uniforme (se repiten con más frecuencia de lo esperado).

Así que la idea es aumentar la longitud de la contraseña pero usando un esquema fácil de recordar (como propone xkcd). Eso es más o menos lo que he hecho en erpwgen (easy to remember password generator :D).

Se trata más de un ejercicio entretenido reinventando la rueda que otra cosa, porque hay muchos generadores que aplican estas ideas con mejores resultados (de hecho mi empresa tiene un password generator bastante potente; hecho en go y que pronto será publicado como Open Source).

Mi herramienta simplente sigue un esquema muy sencillo (el código importante son menos de 100 lineas de Python), cargando un diccionario de MySpell para generar las contraseñas.

Por ejemplo, usando el diccionario es_ES y con el modo verbose para tener más detalles:

$ ./erpwgen.py -v -l es_ES
57805 lines read from es_ES
10829 valid words in the dictionary, (5, 6) letters
12695351727240 possible passwords, entropy ~43 bits

AhijarGuaranCamero1
OciosoMejorOdisea9
AlteaRobraPijama5
MentolNarizBiber1
PoemaHoyadaLavada0
MenearAlbinaSofre9
EntredOjancoMejor1
ColorRodenoEspor5
DisteGraparAnsiol4
OjocheAftosoMartha4

Tras procesar el diccionario tenemos 10829 palabras de 5 o 6 letras, lo que nos da 12695351727240 contraseñas distintas (contando con que añadimos un número al final), que es una entropía de uns 43 bits (en realidad está más cerca de 44).

Las matemáticas son muy sencillas, para el número de contraseñas calculamos las variantes sin repetición (matemáticas de de ESO, ¿no?):

# un número y 10829 palabras agrupadas en 3 sin repetición
10 * 10829! / (10829-3)! = 12695351727240

Para calcular la entropía es simplemente sumar la entropía de 3 palabras de entre 10829 y la entropía de un número del 0 al 9:

(3 * log(10829) / log(2)) + (log(10) / log(2)) = ~43.53

Podemos generar una contraseña más fuerte añadiendo una palabra, por ejemplo:

$ ./erpwgen.py -vl es_ES 4 1
57805 lines read from es_ES
10829 valid words in the dictionary, (5, 6) letters
137439877799100240 possible passwords, entropy ~56 bits

MelarTarcoPapayoFantas1

¡56 bits! Digamos que podemos probar 1 millón de contraseñas por segundo, solo necesitaríamos algo menos de 2285 años para conseguir la contraseña usando fuerza bruta ;).

Para terminar, si te interesa este tema, recomiendo que leas realistic password strength estimation de Dan Wheeler (de Dropbox).

Anotación por Juan J. Martínez, clasificada en: security.

Los comentarios están cerrados: los comentarios se cierran automáticamente una vez pasados 30 días. Si quieres comentar algo acerca de la anotación, puedes hacerlo por e-mail.

Algunas anotaciones relacionadas: