Generando sal para el hash que se produce en el servidor y el cliente

0

Digamos que tengo una llamada a la API que se supone que comprueba si existe una dirección de correo electrónico en la base de datos, sin transmitir la dirección de correo electrónico real. Para ese propósito, decidí almacenar el hash SHA256 de la dirección de correo electrónico en la base de datos, y actualicé al cliente para enviar el hash SHA256 del correo electrónico en la llamada a la API (en lugar de la dirección de correo electrónico de texto simple).

¿Cómo puedo hacer que esto sea más seguro utilizando sal al calcular el hash?

Según mi entendimiento, tener una sal fija es casi lo mismo que no tener sal en absoluto. ¿Hay alguna forma en que pueda tener sal única por dirección de correo electrónico, pero de tal manera que tanto el servidor como el cliente puedan calcularlas?

¿Tendría sentido algo como esto? Si no, ¿puede explicar por qué?

salt = sha256(email)
email_hash = salt + "|" + sha256(email + salt)

Considere la siguiente cita:

  

El valor de sal no es secreto y puede generarse al azar y almacenarse   con la contraseña hash. Un gran valor de sal evita la precomputación   ataques, incluidas las tablas de arco iris, asegurando que cada usuario   La contraseña está hash únicamente. Esto significa que dos usuarios con la misma   La contraseña tendrá diferentes hashes de contraseña (asumiendo diferentes sales   son usados). Para tener éxito, un atacante necesita calcular previamente las tablas.   para cada valor de sal posible. La sal debe ser lo suficientemente grande, de lo contrario   un atacante puede hacer una tabla para cada valor de sal.

No estoy seguro de si me estoy perdiendo algo o no, pero esto significa que incluso si la sal no es un secreto ni es aleatoria, y todos saben cómo calcular la sal para una dirección de correo electrónico, todavía evitaría que el atacante no puede recuperar direcciones de correo electrónico de hashes utilizando tablas de arco iris. Debido a que cada correo electrónico sería hash único. ¿Es eso correcto?

    
pregunta xx77aBs 29.06.2018 - 11:50
fuente

1 respuesta

3
  

¿Tendría sentido algo como esto? Si no, ¿puede explicar por qué?

El proceso probablemente requeriría un hashmac en lugar de un simple sha256 . Además, me dirigiría a las funciones de cifrado de hash de su idioma en lugar de a las funciones de hashing simples (es decir, password_hash en PHP en lugar de md5 ).

Por último, no has incluido tu hash en tu ejemplo: tu salt = sha256(email) es el hash de unsalt que el atacante quisiera saber.

  

¿Esto significa que incluso si la sal no es un secreto ni aleatorio?

Por definición, la sal es aleatoria, por lo que la pregunta es contradictoria

  

aún evitaría que el atacante recupere las direcciones de correo electrónico de los hash utilizando tablas de arco iris

No, porque la sal debe ser aleatoria (y única para cada campo). Si la sal no es aleatoria y predecible a partir de sus datos originales, o si la sal no es única, entonces se puede usar la tabla del arco iris (tal vez el atacante deba forjar esa tabla primero, así que eso es más difícil que la sal, pero aún es factible).

  

Porque cada correo electrónico sería hash único.

Pero dos llamadas del método hashing con los mismos datos producen el mismo resultado, y por lo tanto es una amenaza. Si su "sal" no es aleatoria, aún tendrá hashes únicos (de lo contrario, escriba su correo electrónico porque ha encontrado una colisión) pero una tabla de arco iris está destinada a hacer coincidir un hash con un valor sin formato correspondiente correspondiente, por lo que Seguiré siendo vulnerable (incluso si el atacante probablemente tenga que forjar esa tabla de arco iris primero en lugar de reutilizar una desde la web).

Así que para retroceder en tu caso, lo que quieres es:

  

Una API que puede saber si un correo electrónico "existe" (se encuentra en la lista blanca de un servidor) sin enviar el correo electrónico mismo

Si los servidores conocen el correo electrónico simple, entonces puede dejar que el cliente genere un salt aleatorio, haga un password_hash de ese email+salt y envíe este hash y el salt al servidor. El servidor tomará cada correo electrónico que tenga, realizará el proceso de hash y, si se encuentra una coincidencia, el servidor devuelve "el correo electrónico existe" al cliente.

Si el servidor no conoce el correo electrónico simple, sino solo una versión hash con sal, entonces puede tratar este correo electrónico como una contraseña, que se envía de forma segura y segura.

Si aún no desea enviar el correo electrónico en claro sobre el transporte seguro, entonces no puede enviar un valor de hash con sal al azar (es el objetivo de los valores de hash con sal al azar: tenga un resultado único para cada llamada y no se capaz de obtener cualquier información de ese valor, por lo que el servidor no podrá obtener la información "este correo electrónico está en la lista blanca"). Luego, necesitará un id para cada hash, que actuará como un identificador público único de ese hash (de la misma manera que el inicio de sesión es un identificador público de la contraseña de hash del servidor). El servidor luego devolverá el hash para este id y el cliente podrá password_verify it usando el correo electrónico que conoce (por lo que el correo electrónico no se transfiere, pero el hash).

    
respondido por el Xenos 03.07.2018 - 14:10
fuente

Lea otras preguntas en las etiquetas