# Función de derivación de clave

En criptografía, una función de derivación de clave (también conocida como KDF por sus siglas en inglés) deriva una o más claves secretas de un valor secreto como una clave maestra, una contraseña o una frase de contraseña, usando una función pseudoaleatoria. Las KDF se pueden utilizar para extender claves en otras más largas o para obtener claves en un cierto formato, por ejemplo para convertir un elemento de grupo resultado de Diffie-Hellman en una clave simétrica para usar con AES. Las funciones hash criptográficas de clave son ejemplos populares de funciones pseudoaleatorias usadas para derivación de clave.

## Usos de KDF

* Junto con parámetros no secretos para derivar una o más claves de un valor secreto común (conocido en ocasiones como «diversificación de clave»). Este uso puede evitar que un atacante obtenga una clave derivada obteniendo información útil sobre el valor secreto de entrada o de las otras claves derivadas. Se puede utilizar también una KDF para asegurarse de que las claves derivadas tengan otras propiedades deseables, como evitar «claves débiles» en algunos sistemas de encriptación específicos.
* El uso más común de las KDF es el hash de contraseñas para verificación de contraseñas, como en el archivo passwd o en contraseñas shadow. Las KDF tienen las características deseadas para una «función de contraseña hash», a pesar de que no fueron originalmente diseñadas para este propósito. Los parámetros no secretos se denominan «sal» en este contexto.
    En 2013 se anunció una Password Hashing Competition para elegir un nuevo algoritmo estándar para el hash de contraseña. El 20 de julio de 2015 finalizó la competición y se nombró a Argon2 como el ganador final. Otros cuatro algoritmos recibieron un reconocimiento especial: Catena, Lyra2, Makwa y yescrypt.
* Como componentes de protocolos de establecimiento de clave multiparte. Ejemplos de estas funciones de derivación de clave incluyen a KDF1, definido en IEEE Std 1363-2000, y funciones similares en ANSI X9.42.
* Para derivar claves de contraseñas o frases de contraseña secretas.
* Para derivar claves de diferente longitud de las introducidas. Un ejemplo de KDF diseñada para este propósito es HKDF.
* Extensión de claves y fortalecimiento de claves.

### Extensión de claves y fortalecimiento de claves

Las funciones de derivación de clave se usan también en aplicaciones para derivar claves de contraseñas o frases de contraseña secretas, que típicamente no tienen las propiedades deseadas para usarse directamente como claves criptográficas. En estas aplicaciones, se recomienda generalmente que la función de derivación de clave se haga deliberadamente lenta para frustrar ataques de fuerza bruta o ataques de diccionario sobre el valor de entrada.
Este uso se puede expresar como DK = KDF(key, salt, iterations), donde DK es la clave derivada, KDF es la función de derivación de clave, key es la clave o contraseña original, salt es un número aleatoria que actúa como sal criptográfica, y iterations se refiere al número de iteraciones de una subfunción. La clave derivada se usa en lugar de la clave o contraseña original como clave del sistema. Los valores de la sal y el número de iteraciones (si no es fijo) se almacenan con la contraseña hash o se envían como texto plano con un mensaje encriptado.
La dificultad de un ataque de fuerza bruta aumenta con el número de iteraciones. Un límite práctico en el número de iteraciones es la renuencia de los usuarios para tolerar un retraso perceptible al iniciar sesión en un dispositivo o en ver un mensaje desencriptado. El uso de sal previene que los atacantes precalculen un diccionario de claves derivadas.
Una aproximación alternativa, llamada fortalecimiento de clave, extiende la clave con una sal aleatoria, tras lo cual (al contrario que en la extensión de clave) borra de forma segura la sal. Esto fuerza a que tanto el atacante como los usuarios legítimoss realicen una búsqueda de fuerza bruta del valor de sal. Aunque el artículo que introdujo la extensión de clave mencionaba esta técnica previa y eligió intencionadamente un nombre diferente, el término «fortalecimiento de clave» se usa a menudo para referirse a la extensión de clave.

## Historia

La primera función de derivación de clave basada en contraseña deliberadamente lenta se llamó «crypt» (o «crypt(3)» por su página de man), y fue inventada por Robert Morris en 1978. Encripta una constante usando los 8 primeros caracteres de la contraseña del usuario como clave, realizando 25 iteraciones de un algoritmo de encriptación DES modificado (en el que se usa la lectura de un número de 12 bits del reloj del ordenador para perturbar los cálculos). El número de 64 bits resultante se codifica como 11 caracteres imprimibles y se almacenan en el archivo de contraseña de Unix. Aunque fue un gran avance en su tiempo, el aumento en la velocidad de los procesadores desde la era de PDP-11 ha hecho posibles los ataques de fuerza bruta contra crypt, y los avances en almacenamiento han hecho la sal de 12 bits inadecuada. El diseño de la función crypt también limita la contraseña del usuario a 8 caracteres, lo que limita el espacio de claves y hace que las frases de contraseña fuertes sean imposibles.
Las funciones de derivación de clave basadas en contraseñas modernas, como PBKDF2 (especificada en RFC 2898), usan un hash criptográfico, como SHA-2, más sal (por ejemplo 64 bits o más) y un alto número de iteraciones (a menudo decenas o cientos de miles).
El NIST requiere al menos 128 bits de sal aleatoria y una función criptográfica aprobada por el NIST, como la serie SHA o AES (MD5 no está aprobada). Aunque un alto rendimiento es una propiedad deseable en funciones hash de propósito general, se necesita lo contrario para aplicaciones de seguridad de contraseñas en las que la defensa contra los ataques de fuerza bruta es una preocupación primaria. El uso en aumento de hardware paralelo en masa como GPU, FPGA e incluso ASIC para ataques de fuerza bruta ha hecho la selección de algoritmos adecuados aún más importante ya que un buen algoritmo debe no solo forzar una cierta cantidad de coste computacional en CPUs, sino también resistir las ventajas coste/rendimiento de las plataformas paralelas masivas para estas tareas. Se han diseñado varios algoritmos específicamente para este propósito, incluyendo bcrypt, scrypt y, más recientemente, Argon2 (el ganador de la Password Hashing Competition). La fuga de datos a gran escala de Ashley Madison en la que los atacantes robaron aproximadamente 36 millones de hashes de contraseñas ilustra la importancia de la selección de algoritmo para asegurar contraseñas. Aunque se empleó bcrypt para proteger los hashes (haciendo los ataques de fuerza bruta a gran escala caros y largos), una proporción significativa de las cuentas comprometidas contenía un hash de contraseña basado en el algoritmo de propósito general MD5, lo que hizo posible que alrededor de 11 millones de contraseñas fueran descifradas en cuestión de semanas.
En junio de 2017, el NIST publicó una nueva revisión de sus directrices de autenticación digital, NIST SP 800-63B-3,$^{:5.1.1.1}$ afirmando que «los verificadores deben almacenar los secretos memorizados [por ejemplo, contraseñas] de forma que sean resistentes a ataques offline. Los secretos memorizados tienen que someterse a sal y hash usando una función de derivación de clave unidireccional adecuada. Las funciones de derivación toman una contraseña, una sal y un factor de coste como entradas y generan un hash de contraseña. Su propósito es hacer que cada intento de adivinar una contraseña por un atacante que ha obtenido un archivo hash de contraseña sea caro y por tanto el coste de estos ataques sea alto o prohibitivo» y que «la sal debe ser de al menos 32 bits de longitud y se debe escoger arbitrariamente de forma que minimice las coincidencias con otros hashes almacenados».