Anonimización mejor que solo un hash

0

Estoy tratando de ayudar a anonimizar a los usuarios pero aún les doy algunos controles. Por lo tanto, esto es diferente a decir, anonimizar un conjunto de datos donde nunca tendrá que volver a los usuarios originales.

Déjame darte un ejemplo. Quiero que un usuario ingrese su dirección de correo electrónico para iniciar sesión en mi sistema, pero no quiero almacenar la dirección de correo electrónico. Quiero asignar a ese usuario un UUID que luego usaré. Sin embargo, si el usuario pierde el identificador aleatorio, debe poder volver a ingresar su dirección de correo electrónico y luego volver al sistema.

La respuesta más simple a esto es un hash. Por supuesto que podría almacenar el hash junto al UUID. Si pierden el UUID, pueden volver y puedo volver a aplicar la contraseña. Por otro lado, si mi sistema se divide, los malos pueden simplemente realizar un ataque de diccionario en una lista de direcciones de correo electrónico y luego volver a identificar los UUID.

En primer lugar, ¿hay una forma estándar de hacer esto? bcrypt y PBKDF2 me vienen a la mente, pero obviamente no puedo almacenar una tupla de <email, salt, iterations> sin hacer que el trabajo de los intrusos sea aún más fácil.

No me gusta inventar nuevas cosas de seguridad, pero he tenido una idea. Básicamente, almaceno <SHA512(email), salt, iterations> y luego almaceno <PBKDF2(email, salt, iterations), UUID> .

De esa forma tienen que atacar primero el diccionario de la primera tabla, y luego usar los resultados de eso para realizar ataques individuales del diccionario en cada fila de la segunda tabla, lo que debería ralentizar las cosas.

    
pregunta Paul Fremantle 07.07.2016 - 19:47
fuente

2 respuestas

1

Mantenga las cosas simples, si desea el anonimato, no use el correo electrónico para los inicios de sesión.

Haga que su usuario genere un par de claves asimétricas para autenticarse en su sistema, llame a esto la clave de inicio de sesión .

Cuando el usuario desea publicar un mensaje en su sistema, el usuario genera un nuevo par de claves asimétricas, llámelo la clave de datos . El usuario luego firmaría su mensaje con la clave de datos y cifraría la clave de datos privados con su clave de inicio de sesión pública dirigida a ellos mismos. El usuario enviaría la clave de datos privados cifrados, la clave de datos públicos y el mensaje firmado.

Para editar el mensaje publicado, el usuario descarga la clave de datos cifrados y la descifra con su clave privada. Y luego firman el mensaje con la clave de datos privada. Su sistema sabe que los mensajes nuevos son generados por el mismo usuario que el original, porque ambos mensajes están firmados por la misma clave de datos públicos.

Ten cuidado:

  1. muchas implementaciones de criptografía asimétrica adjuntan el ID de la clave de cifrado a un mensaje cifrado, para que el destinatario de un mensaje pueda identificar qué clave utilizar para descifrar el mensaje. Desea asegurarse de cifrar la clave de datos privados sin agregar estos metadatos.

  2. un atacante que logra observar quién descargó qué clave privada cifrada sería capaz de observar qué usuario descargó qué clave y hacer una estimación razonable de quién está haciendo qué. Puede evitarlo obligando a todos los usuarios a descargar todas las claves privadas encriptadas (o una parte razonable de ellas).

  

Básicamente, almaceno <SHA512(email), salt, iterations>

Si está almacenando el SHA512 del correo electrónico de los usuarios, ¿no sería tan fácil identificar a los usuarios como crear una tabla de arco iris SHA512?

    
respondido por el Lie Ryan 09.07.2016 - 07:33
fuente
0
  

Si el usuario pierde el identificador aleatorio, debe poder volver a ingresar su dirección de correo electrónico y luego volver al sistema.

Para adquirir esa función, no tiene más remedio que almacenar un hash de la dirección de correo electrónico. Además, la sal no puede ser secreta porque el usuario ya ha olvidado todo, excepto su dirección de correo electrónico.

Las direcciones de correo electrónico son de baja entrada, como las contraseñas, así que use un Hash de contraseña (lento)

  • Se suele recomendar BCrypt , pero asegúrese de ejecutar un hash SHA-2 rápido en los datos de entrada, por lo que BCrypt no truncará la entrada súper larga
  • PBKDF2 pero eso es menos resistente a GPU porque tiene menos requisitos de memoria.
  • SCrypt es mejor que BCrypt si tiene un factor de trabajo suficientemente alto. De lo contrario es peor contra las GPUs. (de nuevo, debido a requisitos de memoria más altos o más bajos)
  • El ganador de la Competición de hash de contraseñas puede ser incluso mejor que el mencionado anteriormente, pero aún no ha superado la prueba del tiempo, por lo que No lo uses todavía. Se llama Argon2 y tiene configuraciones de Factor de trabajo separadas para el tiempo de CPU y la carga de memoria. (bonito!)
  • Se puede usar SHA-2 repetitivo en lugar de PBKDF2 (aún no es resistente a GPU), pero esto es más difícil de implementar la repetición de manera eficiente (es decir, para ser resistente a la fuerza bruta) porque SHA-2 es en realidad un Propósito General (Rápido ) Hash.

La mayoría de estas opciones generan sal aleatoria de forma predeterminada, ¡pero debes verificar si este es el caso!

Es mejor incluir un poco de pimienta (~ 72 bits de entropía) antes de la entrada antes del hash. Pepper puede ser el mismo para todos sus usuarios, pero debe almacenarse en un archivo fuera de la base de datos para que no se pueda encontrar ese componente a través de Inyección SQL.

Asegúrese de que su factor de trabajo requiera aproximadamente 100 ms (con la protección DoS adecuada) en su hardware de destino (sabiendo que los atacantes usarán un hardware más rápido para la fuerza bruta)

Ten en cuenta que de todas formas las direcciones de correo electrónico muy pueden ser forzadas brutalmente , ¡así que no dejes que el hash sea robado! También es relevante que un atacante pueda verificar rápidamente la presencia de una dirección de correo electrónico en particular.

Sería prudente observar otras precauciones de seguridad que puede tomar, como Separación de usuarios de bases de datos SQL para contener posibles ataques SQLi. También asegúrese de que su sistema esté seguro en general.

  

No me gusta inventar nuevas cosas de seguridad, pero he tenido una idea. Básicamente, almaceno <SHA512(email), salt, iterations> y luego almaceno <PBKDF2(email, salt, iterations), UUID> .

No hay ningún beneficio en agregar complejidad aquí. Si desea que el atacante tenga que hacer más trabajo, solo suba el Factor de trabajo y use Pepper como se describe.

    
respondido por el George Bailey 07.10.2016 - 15:35
fuente

Lea otras preguntas en las etiquetas