"crypt" --- Función para verificar contraseñas Unix
***************************************************

**Código fuente:** Lib/crypt.py

======================================================================

Este módulo implementa una interfaz para la rutina *crypt(3)*, el cual
es una función hash unidireccional basada en un algoritmo DES
modificado; consulte la página del manual de Unix para obtener más
detalles. Los posibles usos incluyen el almacenamiento de contraseñas
cifradas para que puedas verificar las contraseñas sin almacenar la
contraseña real o intentar descifrar contraseñas Unix con un
diccionario.

Tenga en cuenta que el comportamiento de este módulo depende en la
implementación real de la rutina *crypt(3)* en el sistema en
ejecución. Por lo tanto, cualquier extensión disponible en la
implementación actual también estará disponible en este módulo.

Disponibilidad: Unix. No disponible en VxWorks.


Métodos de *hashing*
====================

Nuevo en la versión 3.3.

El módulo "crypt" define la lista de métodos de cifrado (no todos los
métodos están disponibles en todas las plataformas):

crypt.METHOD_SHA512

   Un método de formato modular *crypt* con *salt* de 16 caracteres y
   hash de 86 caracteres basado en la función hash SHA-512. Este es el
   método más fuerte.

crypt.METHOD_SHA256

   Otro método de formato modular *crypt* con *salt* de 16 caracteres
   y hash de 43 caracteres basado en la función hash SHA-256.

crypt.METHOD_BLOWFISH

   Otro método de formato modular *crypt* con *salt* de 22 caracteres
   y hash de 31 caracteres basado en el cifrado Blowfish.

   Nuevo en la versión 3.7.

crypt.METHOD_MD5

   Otro método de formato modular *crypt* con *salt* de 8 caracteres y
   hash de 22 caracteres basado en la función hash MD5.

crypt.METHOD_CRYPT

   El método tradicional con un *salt* de 2 caracteres y hash de 13
   caracteres. Este es el método más débil.


Atributos del módulo
====================

Nuevo en la versión 3.3.

crypt.methods

   Una lista de algoritmos hash de contraseña disponibles, como
   objetos "crypt.METHOD_*". Esta lista está ordenada de la más fuerte
   a la más débil.


Funciones del módulo
====================

El módulo "crypt" define las siguientes funciones:

crypt.crypt(word, salt=None)

   *word* normalmente será la contraseña de un usuario tal como se
   escribe en un prompt o en una interfaz gráfica. El *salt* opcional
   es una cadena retornada por "mksalt()", uno de los valores
   "crypt.METHOD_*" (aunque no todos pueden estar disponibles en todas
   las plataformas), o una contraseña completa encriptada que incluye
   *salt*, como lo retorna esta función. Si no se proporciona *salt*,
   se utilizará el método más fuerte (como lo retornado por
   "methods()").

   La verificación de una contraseña generalmente se hace pasando la
   contraseña de texto plano como *word* y los resultados completos de
   una llamada anterior a "crypt()", que debería ser igual a los
   resultados de esta llamada.

   *salt* (ya sea una cadena aleatoria de 2 o 16 caracteres,
   posiblemente con el prefijo "$digit$" para indicar el método) que
   se utilizará para perturbar el algoritmo de cifrado. Los caracteres
   en *salt* deben estar en el conjunto "[./a-zA-Z0-9]", con la
   excepción del formato modular *crypt* que antepone un "$digit$".

   Retorna una contraseña con hash como una cadena, que estará
   compuesta por caracteres del mismo alfabeto que *salt*.

   Dado que algunas extensiones de *crypt(3)* permiten diferentes
   valores, con diferentes tamaños en *salt*, se recomienda utilizar
   la contraseña encriptada completa como *salt* al buscar una
   contraseña.

   Distinto en la versión 3.3: Acepta los valores "crypt.METHOD_*"
   además de las cadenas para *salt*.

crypt.mksalt(method=None, *, rounds=None)

   Retorna un *salt* generado aleatoriamente del método especificado.
   Si no se proporciona ningún método (*method*), se utiliza el método
   mas fuerte disponible según lo retornado por "methods()".

   El valor de retorno es una cadena adecuada para pasar como
   argumento *salt* a "crypt()".

   *rounds* especifica el número de rondas para "METHOD_SHA256",
   "METHOD_SHA512" y "METHOD_BLOWFISH". Para "METHOD_SHA256" y
   "METHOD_SHA512" debe ser un entero entre "1000" y "999_999_999", el
   valor predeterminado es "5000".  Para "METHOD_BLOWFISH" debe ser
   una potencia de dos entre "16" (2^4) y "2_147_483_648" (2^31), el
   valor predeterminado es "4096" (2^12).

   Nuevo en la versión 3.3.

   Distinto en la versión 3.7: Se agregó el parámetro *rounds*.


Ejemplos
========

Un simple ejemplo que ilustra el uso típico (se necesita una operación
de comparación de tiempo constante para limitar la exposición a los
ataques de tiempo. "hmac.compare_digest()" es adecuado para este
propósito):

   import pwd
   import crypt
   import getpass
   from hmac import compare_digest as compare_hash

   def login():
       username = input('Python login: ')
       cryptedpasswd = pwd.getpwnam(username)[1]
       if cryptedpasswd:
           if cryptedpasswd == 'x' or cryptedpasswd == '*':
               raise ValueError('no support for shadow passwords')
           cleartext = getpass.getpass()
           return compare_hash(crypt.crypt(cleartext, cryptedpasswd), cryptedpasswd)
       else:
           return True

Para generar un hash de una contraseña utilizando el método más fuerte
disponible y compararlo con el original:

   import crypt
   from hmac import compare_digest as compare_hash

   hashed = crypt.crypt(plaintext)
   if not compare_hash(hashed, crypt.crypt(plaintext, hashed)):
       raise ValueError("hashed version doesn't validate against original")
