¿Cómo almacenar datos privados de forma segura y de acceso público?

11

Es posible que la tarea no se pueda resolver en una formulación tan amplia como en el título, pero este es mi escenario (que es algo similar, por ejemplo, a las suscripciones a boletines informativos y, por lo tanto, ciertamente ya se ha pensado)

Quiero implementar una base de datos en un servidor web donde se almacenan datos privados sobre los usuarios. Se supone que los usuarios no deben tener un nombre de inicio de sesión elegante, sino que deben ser "validados por correo electrónico", es decir, el acceso a un buzón debe ser suficiente para la autenticación.

Los usuarios deben poder crear, actualizar y eliminar solo sus propios datos. La administración central debe poder exportar los datos del servidor web a un host seguro.

El escenario de ataque es que el servidor web junto con todos los datos (incluidos los scripts de la página web y la base de datos) se ven comprometidos. El requisito es que los datos privados almacenados allí antes el compromiso permanezca protegido (suponiendo que no se intente acceder a más usuarios).

Aquí están mis ideas hasta ahora: para autenticar solo tengo los usuarios email .

  • Un nuevo ingresa su email en un formulario, lo que hace que hash(email) + publicencrypt(email) + random nonce + timestamp se almacene representando al usuario y al usuario se le envía un correo con una URL con parámetros random nonce y email . (Como solo hay email (protegido) y no username (desprotegido) password (protegido), no se pueden usar cosas como la sal y tengo que recurrir a hash(email) , ¿no?).
  • Lo mismo sucede con un usuario existente, donde solo el hash(email) será el mismo que en cualquier intento anterior. publicencrypt(email) , random nonce y timestamp serán diferentes.
  • Cualquier persona que acceda a una URL con los parámetros email y nonce como se generaron anteriormente puede realizar operaciones en el registro de la base de datos correspondiente después de verificar: ¿Existe un registro con hash(email) y nonce coincidentes y no demasiado antiguo? código%? En caso afirmativo, el usuario puede proceder. Tenga en cuenta que durante la sesión web de este usuario, el texto claro timestamp está disponible.
  • La exportación al host de administración central seguro ocurre exportando los datos cifrados tal como están. El descifrado ocurre con la clave privada que coincide con la clave pública utilizada para cifrar (esta última se considera pública porque reside en el servidor comprometible).

La adición de una nueva entrada se completa en este punto, agregando una bandera email al registro. Por supuesto, borrar el registro es fácil. Mostrar datos no confidenciales (por ejemplo, cuándo se creó o modificó por última vez la entrada) también es una tarea trivial.

Mi problema es: ¿Cómo manejar los datos privados adicionales de forma segura? Es posible que solo lo guarde en forma cifrada (como el correo electrónico), pero en ese caso, el contenido ni siquiera se puede mostrar al usuario autenticado. Puede cambiarlo, pero no puede descifrarlo en una sesión web posterior. Esto es, por supuesto, sub-obtimal. Mi única idea es cifrar los datos adicionales con una clave diferente: en lugar de la clave pública de un par de claves asimétricas, use una clave simétrica que es reproducible producida desde isValid , es decir, almacene datos adicionales como %código%. Como el texto claro email está disponible para el propio usuario durante su sesión web, así como en la exportación descifrada en el host seguro, se puede reconstruir symmetricencrypt(data,key_generated_from(email)) .

Veo los siguientes problemas:

  • Dado el formato restringido de las direcciones de correo electrónico (por ejemplo, algunos dominios pueden ocurrir muy a menudo), ¿podría una clave generada a partir del correo electrónico como se describe anteriormente ser lo suficientemente segura?
  • En realidad, dado el formato restringido de las direcciones de correo electrónico, ¿es el email que usé en el concepto básico que asegura que solo el correo electrónico es lo suficientemente bueno? (¿Hay suficiente entropía en las direcciones de correo electrónico, por así decirlo?)
  • ¿Hay un mejor enfoque?
pregunta Hagen von Eitzen 14.12.2015 - 20:48
fuente

2 respuestas

2
  

Un nuevo ingresa su correo electrónico en un formulario, lo que provoca el hash (correo electrónico) +   publicencrypt (correo electrónico) + nonce + timestamp aleatorio para ser almacenado   representando al usuario y al usuario se le envía un correo que contiene una URL   Con parámetros aleatorios, nonce y correo electrónico. (Como solo hay (protegido)   correo electrónico y no (desprotegido) nombre de usuario más (protegido) contraseña, cosas   como la sal no se puede usar y tengo que recurrir al hash (correo electrónico), no   Yo?).

Puede agregar una columna adicional con datos aleatorios adicionales (generados en la suscripción) que se usan solo como sal para el cálculo de hash (una sal aleatoria para el usuario). Eso le daría el mismo efecto que usar el nombre de usuario (no existente). La sal se puede almacenar en texto sin cifrar en la misma fila del correo electrónico, sin ningún problema. Solo usa una sal por usuario, hazlo al azar y estarás bien.

  

Dado el formato restringido de las direcciones de correo electrónico (por ejemplo, algunos dominios pueden   ocurrir muy a menudo), podría una clave generada desde el correo electrónico como se describe   arriba, ¿estar suficientemente seguro?

Use PBKDF2 para mayor seguridad. Esto le brindaría la mayor seguridad posible cuando el único "secreto" que el usuario puede proporcionar es su dirección de correo electrónico.

  

En realidad, dado el formato restringido de las direcciones de correo electrónico, es el   hash (correo electrónico) que utilicé en el concepto básico que protege solo el correo electrónico   lo suficientemente bueno en absoluto? (¿Hay suficiente entropía en las direcciones de correo electrónico, por lo que   hablar?)

Ya ha respondido antes, use un valor de sal almacenado en la base de datos.

  

¿Hay un mejor enfoque?

Probablemente solo por no poner toda su confianza en tener la dirección de correo electrónico como contraseña. Pero si eso es realmente un requisito, no puedes hacerlo mucho mejor. Podría tener información adicional en el servidor para usar en la derivación de clave (derivar clave de correo electrónico + información del servidor), pero esto no mejoraría la seguridad en el escenario de ataque de que el usuario obtenga todos los datos sin conexión. Y, por supuesto, puede usar algún hardware de cifrado (HSM) y la clave derivada como PIN para la clave en el HSM. De esa manera, el atacante no solo debe volcar los datos del servidor e identificar el correo electrónico asociado con cada cuenta, sino que también debe controlar el servidor para que use el HSM para descifrar los datos.

    
respondido por el CristianTM 08.01.2016 - 13:35
fuente
1

Creo que podría estar buscando un sistema de autenticación basado en token. Envían la dirección de correo electrónico, el servidor produce un token y se lo envía a ellos, hacen clic en el enlace que debe enviar el token a su sitio web de alguna forma. El token es aleatorio y válido solo por un tiempo limitado (por ejemplo, 15 minutos, piense en memcache ^. ^) Y se puede actualizar según la acción del usuario. En cuanto al cifrado, podría derivar algo del hash de correo electrónico como clave y nunca conservar la versión simple de la dirección de correo electrónico. Y se niegan a reutilizar hashes en la nueva fase de usuario ...

Como nota al margen, suena muy aterrador usar solo el correo electrónico para obtener acceso. Tenga en cuenta que la mayoría de las aplicaciones que los usuarios tocarán en la actualidad lo primero que verán son los contactos. Por lo tanto, existe una gran posibilidad de que alguien ya tenga una lista de usuarios y acceso.

    
respondido por el user283885 06.01.2016 - 18:02
fuente

Lea otras preguntas en las etiquetas