Está en la página 1de 2

CMO GENERAR EN PYTHON UNA HASH PARA LOS PASSWORDS COMO LA DE GNU LINUX Jose Antonio Molina Jimnez

Para crear una funcin que genere una hash como la de linux, lo primero que debemos entender es cmo genera Linux dicha hash, y qu es cada cosa. Al asignar un password a un usuario, Linux crea una salt que va a combinar con la clave que asignamos al usuario aplicndole al conjunto un algoritmo de cifrado, generndose as la hash que vemos en /etc/shadow. Una salt bsicamente es un conjunto de caracteres generados de forma aleatoria cuya misin es hacer ms difcil el descifrado de la clave frente a scripts que empleen algoritmos basados en ataques de diccionario. Si observamos la hash de un usuario cualquiera del sistema veremos que tiene la forma:

Como vemos, la hash es la siguiente: $6$A82jZvb/$pXcc26.l29pTuX2geL8zPvqriVTobKKSD45Yh5PxYnYg7aTZGNOMdp2gDbvYp jdsvdMO8IZIKKDfj.USnTgbT1 salt $6$A82jZvb/$ password pXcc26.l29pTuX2geL8zPvqriVTobKKSD45Yh5PxYnYg7aTZGNOMdp2gDbvYp jdsvdMO8IZIKKDfj.USnTgbT1 Cmo genera Linux la salt? 1. Los tres primeros caracteres, indican el algoritmo de cifrado: $2$ algoritmo de cifrado blowfish $3$ algoritmo de cifrado sha256 $5$ algoritmo de cifrado md5 $6$ algoritmo de cifrado sha512 Las distribuciones de Linux modernas utilizan sha512 2. 8 caracteres, escogidos de forma aleatoria, a elegir entre una lista que agrupa: Letras minsculas [abcdefghijkl.........z] Letras maysculas [ABCDEFGHIJKL...........Z] Enteros del 0 al 9 [0123456789] Y los caracteres especiales . y / 3. Caracter $ indica el final de la salt. Una salt as generada, se combina con la clave que introducimos por teclado y, al aplicarle un algoritmo de cifrado, da como resultado la hash correspondiente.

CMO GENERAR EN PYTHON UNA HASH PARA LOS PASSWORDS COMO LA DE GNU LINUX Jose Antonio Molina Jimnez
Cmo implementamos todo eso en python? Funciones de python a utilizar: random.randint(n,m) genera un numero entero en el rango n,m crypt.crypt(password,salt) aplica algoritmo de cifrado a la salt y al password list() genera una lista len() cuenta el nmero de elementos en una lista getpass.unix_getpass() captura un password introducido por teclado sin mostrar dicho password en pantalla a medida que ste es introducido. Constantes a utilizar: string.letters devuelve el conjunto de caracteres a,b,c,....,z,A,B,C,...,Z string.digits devuelve una cadena de strings formada por los enteros 0,1,...,9 Esta funcin genera una hash como la de linux y adems, la imprime por pantalla. A partir de aqu, lo nico que tienes que hacer, es cambiarle el nombre a la funcin, e invocarla desde tu script para que asigne el password al usuario en concreto, y por supuesto, editar con el resultado el contenido de /etc/shadow. No olvides editar la ltima: cambia el 'print' por 'return'. El uso de getpass para capturar el password introducido es por razones de seguridad. Esto evitar que el password se vaya imprimiendo en pantalla a medida que se introduce: def main(): import crypt, getpass, string, random #genero lista [a,...,z,A,...,Z,0,'1',..'9','.','/'] chars=list(string.letters)+list(string.digits)+['.']+['/'] lrandom=[] i=0 while (i<8): n=random.randint(0,len(chars)-1) lrandom=lrandom+[chars[n]] i=i+1 salt='$'+'6'+'$'+string.join(lrandom,'')+'$' while True: passwd=str(getpass.unix_getpass('password del usuario: ',None)) confirm_passwd=str(getpass.unix_getpass('confirme el password: ',None)) if (passwd==confirm_passwd): break hashing=crypt.crypt(passwd,salt) print hashing #No olvides cambiar 'print' por 'return' en esta linea si este codigo no esta #en el cuerpo de main. if (__name__=='__main__'): main() El uso de este script produce la funcin hash deseada: