Derivar una contraseña de autenticación a partir de una contraseña de cifrado

1

Estoy creando una aplicación con los siguientes requisitos:

  1. Un cliente inicia sesión con correo electrónico y contraseña. En el servidor, bcrypt(password) se calcula y se compara con lo que está almacenado en la base de datos.
  2. Si la autenticación es exitosa, el servidor envía un bloque de datos cifrados que luego serán descifrados en el cliente. (En algún momento en el pasado, el cliente cifró los datos y los envió al servidor).
  3. La contraseña para los datos cifrados nunca debe enviarse al servidor, por lo que no puedo usar la misma contraseña para la autenticación y el cifrado / descifrado.

Una solución que cumpliría estos requisitos es usar solo dos contraseñas: una para la autenticación y otra para el cifrado / descifrado de los datos. Sin embargo, los usuarios deberán recordar dos contraseñas y podrían mezclarse, enviando accidentalmente la contraseña de descifrado al servidor y violando el tercer requisito.

Una alternativa que requiere solo una contraseña: use la contraseña para el cifrado / descifrado y bcrypt(password) para la autenticación. De esa manera, la base de datos almacenaría bcrypt(bcrypt(password)) y el servidor nunca manejaría la contraseña de cifrado / descifrado.

¿Es algo razonable de hacer o estoy pasando por alto un problema de seguridad? El tiempo de inicio de sesión / cómputo adicional causado por el cálculo de dos hashes no sería un problema.

    
pregunta chrisklaussner 30.12.2016 - 20:59
fuente

2 respuestas

3

La solución más apropiada para este tipo de cosas es un prefijo.

Por ejemplo:

  • clave de autenticación = bcrypt("AUTHENTICATION" + $password)
  • clave de cifrado = bcrypt("ENCRYPTION" + $password)

Sin embargo, debo tener en cuenta que BCrypt no está realmente diseñado para generar claves criptográficas. Es una función de hashing de contraseña, no una función de derivación de clave, y sus propiedades son diferentes. Probablemente podría salirse con la suya, pero sugeriría usar PBKDF2 o un KDF similar para generar la clave de cifrado. En este punto, el uso de un prefijo es redundante, ya que estás usando dos algoritmos completamente diferentes.

    
respondido por el Polynomial 30.12.2016 - 21:40
fuente
0

Trabajo para AgileBits, los creadores de 1Password y describiremos lo que hacemos para cumplir con nuestro nombre de contraseña 1 . De hecho, le daré una versión simplificada , porque hay otras cosas que hacemos en nuestra derivación clave que no son relevantes para esta pregunta.

Las dos claves que nuestros clientes derivan de una contraseña maestra son algo que llamamos una clave de desbloqueo maestra (MUK), que es la clave con la que se encripta la parte secreta del par de claves públicas de un usuario. La otra clave es el SRP-x que se utilizará en el protocolo de autenticación de contraseña remota segura. Ambos son de 256 bits.

Comenzamos con dos sales diferentes, llamaré un salt_auth y el otro salt_enc . Y tenemos dos cadenas de versión diferentes; digamos que son "v1-auth" y "v1-enc ".

Para derivar el SRP-x

ahora en muy pseudo código

deriveKey(salt, password, version, email, accountID)
    s <- HMAC-SHA256(salt, version + username)
    k <- PBKDF2-HMAC-SHA256(password, s, 100000)
    k <- HMAC-SHA256(k, version + accountID)
    return k

Ahora no todos estos pasos son necesarios. Pero hay dos diferencias en la entrada de esto cuando se deriva el SRP-x (para la autenticación) o la clave de desbloqueo principal (para el cifrado). La sal, y la versión.

(Hay otras razones por las que vinculamos el nombre de usuario y la dirección de correo electrónico a la derivación de la clave que no son relevantes para esta discusión. También usamos HKDF en lugar de HMAC-SHA256 para que tengamos algo más adaptable a diferentes tamaños de clave.

Usa PBKDF2 con cuidado

Hagas lo que hagas, no utiliza una ejecución de PBKDF2 para derivar dos claves. Por ejemplo, no use PBKDF2 para generar, digamos, una clave de 256 bits que se divide en dos claves de 128 bits. Pueden suceder cosas malas si haces eso.

    
respondido por el Jeffrey Goldberg 01.01.2017 - 00:35
fuente

Lea otras preguntas en las etiquetas