¿Buen método para almacenar el contenido del usuario encriptado sin almacenar la clave del usuario en texto sin formato?

1

Tengo una serie de requisitos aparentemente contradictorios:

1) Obtenemos contenido para usuarios de terceros; El contenido para ciertos usuarios debe almacenarse encriptado en reposo por razones de cumplimiento

2) El usuario debe poder descifrar y mostrar su contenido a través de una aplicación / api segura

3) Hay muchos usuarios en una cuenta determinada, y todos deberían poder descifrar y ver el contenido de cada uno (lo que implica una clave compartida)

4) Un proceso de trabajo de back-end debería poder descifrar y reprocesar el contenido del usuario en cualquier momento, si queremos (por ejemplo) mejorar nuestra analítica

Si tuviéramos que hacerlo, podríamos sacrificar el # 4 (o quizás hacer que el usuario se autentique para permitirlo).

Naturalmente, no quiero almacenar la clave de cifrado en texto sin formato en cualquier lugar. Sería más conveniente almacenarlo a nivel de usuario, cifrado por un hash PBKDF2 de su contraseña, pero eso introduce un flujo de trabajo incómodo si olvidan su contraseña y necesitan restablecerla (ya que ahora ya no podemos obtener la clave). .)

Tampoco puedo usar la contraseña, porque el acceso al contenido que ya estaba cifrado debería sobrevivir a las solicitudes de cambio de contraseña. Además, por supuesto, no tenemos acceso a la contraseña de texto sin formato en los trabajos async backend worker.

¿Hay una forma generalmente aceptada de hacer esto? P.ej. ¿Podría usar algún tipo de flujo de trabajo 2FA-ish para recuperar un secreto de usuario que nunca almacene localmente, pero que se usa para proteger la clave?

    
pregunta fridgepolice 08.02.2017 - 23:58
fuente

2 respuestas

3

El enfoque habitual es utilizar una clave maestra para cada cuenta que realice la verificación real de cifrado / descifrado / integridad, pero que nunca se almacene en texto sin formato en cualquier lugar. Esta clave maestra debe generarse utilizando un generador seguro de números aleatorios y no debe haber manera de recuperar su valor de texto sin formato.

Encripta la clave maestra con claves por usuario derivadas de las credenciales del usuario (puede usar una función de derivación de claves: use algo más fuerte que PBKDF2 si es posible, como scrypt o argon2) en la contraseña del usuario, o requiera que el usuario tener algún otro tipo de clave criptográfica, como un certificado de cliente TLS). De este modo, cada usuario almacena su propia copia cifrada de la clave maestra para su cuenta. Estas claves maestras cifradas se pueden almacenar en el servidor, ya que son inútiles sin las claves por usuario para descifrarlas. Las claves por usuario nunca se almacenan en el servidor de ninguna forma; son suministrados directamente por el cliente, o se derivan de forma efímera de los datos proporcionados por el cliente (como una contraseña), se utilizan y luego se eliminan.

Si es necesario (para su # 4), también puede cifrar la clave maestra de cada cuenta con otras claves, como por ejemplo para su proceso de trabajo en segundo plano. Por supuesto, entonces acabas de pasar la pelota un paso; ¿Dónde se almacena la clave / credencial-que-genera-una-clave para ese trabajador? ¿Cómo se protege de tal manera que un atacante no pueda simplemente agarrarlo, descifrar las claves maestras correspondientes e ir a la ciudad?

El restablecimiento de la contraseña se vuelve algo complicado. Simplemente cambiar una contraseña es fácil: obtenga la contraseña anterior, descifre la clave maestra, vuelva a cifrarla con la nueva contraseña y guarde la clave maestra recién encriptada en la base de datos. Restablecer una contraseña cuando se desconoce la anterior es más difícil. Las opciones habituales allí (aparte de "no puede, no sin perder todos sus datos cifrados", que supongo que son inaceptables) son dar al usuario un solo uso de claves de recuperación demasiado tiempo para ser usado para contraseñas normales pero se puede usar para descifrar la clave maestra cuando sea necesario (lo que significa que tendría una versión de la clave maestra cifrada con la clave estándar por usuario y otra con la clave de recuperación del usuario), y requiera uno de esos para restablecer la contraseña, o para que otro usuario autorizado tenga acceso a los datos que acrediten al usuario que está restableciendo su contraseña, y use las credenciales del usuario para desbloquear la copia de la clave maestra del usuario comprobante y luego cifrarla con la clave de usuario que se restablece y almacene esa clave maestra recién encriptada (ya que tiene varios usuarios por "cuenta", esto funcionaría lo suficientemente bien siempre que ninguna cuenta haga que todos olviden sus contraseñas al mismo tiempo).

    
respondido por el CBHacking 09.02.2017 - 01:53
fuente
1

¿Qué tal un servicio de cifrado dedicado / demonio que se ejecuta en su servidor web?

El servicio tomaría una contraseña maestra (conocida por usted) y necesitaría reingresarse en el reinicio del servidor. Puede utilizar una función de derivación de clave para crear una clave de cifrado en memoria.

Los datos pueden luego ser encriptados o condenados a voluntad por el servicio que consume la aplicación web y el proceso del empleado administrativo.

    
respondido por el ste-fu 09.02.2017 - 01:49
fuente

Lea otras preguntas en las etiquetas