Estamos en
un momento en el que el acceso a múltiples servicios de
Internet necesita de una gran cantidad de claves. Una política
posible para administrarlas es usar la misma clave para todos
ellos, lo que tiene la ventaja de que es fácil de recordar
y la desventaja de que si hay un fallo en mi cuenta de 'foo' y
mi clave se revela entonces mis cuentas en 'bar' y 'baz' podrían
verse comprometidas "de rebote".
Por otro lado
hay un gran número de passwords que no es necesario recordar
porque el navegador lo hace por nosotros o quedan almacenadas
por ejemplo en el programa de acceso a Internet y no hay que teclearlas
cada vez. Esto hace deseable un método de generar claves
con las siguientes características:
La
solución que propongo en esta página cumple las tres
condiciones anteriores. Produce claves aparentemente aleatorias,
por tanto difíciles de recordar -sin embargo véase
lo dicho arriba- pero que a diferencia de las claves realmente aleatorias
pueden ser posteriormente reproducidas recordando sólo una
clave maestra y el nombre de usuario u otra cadena a la que estén
asociados.
Veamos un ejemplo
de uso. Queremos una clave de 10 caracteres (la longitud por defecto)
para nuestra cuenta en godofredo@foo.es. La clave no se ve al
escribirse.
Ahora probemos
a generar una clave más segura (16 caracteres) para nuestra
conexión a Internet. Para que esto tenga sentido su clave
maestra debería ser al menos tan difícil de adivinar
por fuerza bruta como esta, vea nuestras otras páginas
sobre passwords seguros.
[prompt]$ python
genera_claves.py 16
Nombre de usuario: Conexión a Internet
Clave maestra :
Confirme clave:
Clave: xm8CLseixmy46hTH
Hay que tener
mucha atención a la cadena que ponemos como nombre de usuario
-no hay problema en apuntarlas en un cuadernillo- porque si la
cambiamos sólo en un caracter (igual que pasa con la clave
maestra claro) la clave resultante es totalmente diferente. Vea
por ejemplo lo que ocurre si olvidamos la tilde en el ejemplo
anterior.
[prompt]$ python
genera_claves.py 16
Nombre de usuario: Conexion a Internet
Clave maestra :
Confirme clave:
Clave: PIfTHjh59M0ort3u
El script
que realiza todo esto es una muestra de la potencia y sencillez
de uso de Python. Funciona sin cambios en Linux, Windows y otras
plataformas y la función principal ocupa apenas 6 líneas.
Vamos a ver
esa función con algún detalle:
import base64
import getpass
import sha
import sys
def genera_clave(username, clavemaestra, longitud):
"""Produce
a partir de un nombre de usuario y una clave
maestra, una
clave de longitud hasta 27 caracteres """
m
= sha.new()
m.update(username)
m.update(clavemaestra)
cadena
= m.digest()
cadena
= base64.encodestring(cadena)
return
cadena[:longitud]
En primer
lugar se genera un nuevo hash con sha.new().
Se le añade la información del nombre de usuario
y la clave maestra con m.update(username) y m.update(clavemaestra).
Se obtiene a continuación el resumen con m.digest()
que son 160 bits, dichos bits se pasan a traves de base64.encodestring()
(el equivalente de uuencode) para obtener una representación
imprimible de parte de esos bits.
Se tienen en
definitiva una serie de caracteres (10 por defecto) escogidos
de entre un conjunto de 64 (6 bits). Luego por ejemplo con 10
caracteres se obtienen 6410 posibles claves. Este espacio de claves
tarda en ser agotado casi 37.000 años si se prueban un
millón de claves por segundo lo que, desde luego, no está
al alcance de cualquiera.
Referencias: