Generazione di sale per l'hash che si verifica su server e client

0

Diciamo che ho una chiamata API che dovrebbe verificare se l'indirizzo e-mail esiste nel DB, senza trasmettere l'indirizzo e-mail effettivo. A tal fine, ho deciso di archiviare l'hash SHA256 dell'indirizzo e-mail nel DB e di aggiornare il client per inviare l'hash SHA256 dell'email nella chiamata API (anziché l'indirizzo e-mail in chiaro).

Come posso renderlo più sicuro usando Salt quando si calcola l'hash?

Secondo la mia comprensione, avere un sale fisso è praticamente lo stesso di non avere affatto sale. C'è un modo in cui posso avere un unico sale per indirizzo email, ma in modo tale che sia il server che il client possono calcolarli?

Qualcosa del genere avrebbe senso? In caso contrario, puoi spiegare perché?

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

Considera la seguente citazione:

The salt value is not secret and may be generated at random and stored with the password hash. A large salt value prevents precomputation attacks, including rainbow tables, by ensuring that each user's password is hashed uniquely. This means that two users with the same password will have different password hashes (assuming different salts are used). In order to succeed, an attacker needs to precompute tables for each possible salt value. The salt must be large enough, otherwise an attacker can make a table for each salt value.

Non sono sicuro se mi manca qualcosa o no, ma questo significa che anche se il sale non è un segreto né casuale, e tutti sanno come calcolare il sale per un indirizzo email, impedirebbe comunque il attaccante dal recupero degli indirizzi email dagli hash utilizzando le tabelle arcobaleno. Perché ogni email verrebbe sottoposta ad hash in modo univoco. È corretto?

    
posta xx77aBs 29.06.2018 - 11:50
fonte

1 risposta

3

Would something like this make sense? If not, can you please explain why?

Probabilmente il processo richiede un hashmac invece del semplice sha256 . Inoltre, vorrei utilizzare le funzioni di criptaggio-hashing della tua lingua invece delle semplici funzioni di hashing (es: password_hash in PHP invece di md5 ).

Infine, non hai saltato il tuo hash nel tuo esempio: il tuo salt = sha256(email) è l'hash unsalt che l'utente malintenzionato vorrebbe sapere.

Does this mean that even if salt isn't a secret nor random

Per definizione, salt è casuale, quindi la domanda è contraddittoria

it would still prevent the attacker from recovering email addresses from hashes using rainbow tables

No, perché il sale deve essere casuale (e unico per ogni campo). Se il sale non è casuale e prevedibile dai tuoi dati originali, o se il sale non è univoco, allora puoi usare la tavola arcobaleno (forse l'attaccante dovrà prima forgiare quella tabella, quindi è più difficile di niente sale, ma è ancora fattibile).

Because each email would be hashed uniquely.

Ma due chiamate del metodo di hashing con gli stessi dati producono lo stesso risultato e quindi rappresentano una minaccia. Se il tuo "sale" non è casuale, avrai comunque hash univoci (altrimenti scrivi la tua email perché hai trovato una collisione) ma una tabella arcobaleno è pensata per abbinare un hash a un valore raw semplice corrispondente, quindi tu Sarai comunque vulnerabile (anche se l'attacker dovrà probabilmente forgiare quella tabella arcobaleno prima di riutilizzarne una dal web).

Quindi, per ricadere sul caso, quello che vuoi è:

An API that can tell if an email "exists" (is on a server's whitelist) without sending the email itself

Se i server conoscono la semplice e-mail, allora puoi lasciare che il client generi un salt casuale, fai un password_hash di quel email+salt e invia questo hash e il sale al server. Il server prenderà quindi ogni e-mail che ha, eseguirà il processo di hash e, se viene trovata una corrispondenza, il server restituisce "email esiste" al client.

Se il server non conosce l'e-mail semplice, ma solo una versione con hash salato, puoi trattare questa e-mail come una password, che viene inviata in chiaro sulla connessione protetta.

Se non vuoi ancora inviare l'email in un trasporto sicuro e protetto, non puoi inviare un valore con hash casuale salato (è l'obiettivo dei valori hash con salato casuale: avere un risultato unico per ogni chiamata e non essere in grado di ottenere qualsiasi informazione da quel valore, in modo che il server non sia in grado di ottenere l'informazione "questa e-mail è in whitelist"). Quindi, sarà necessario un id per ogni hash, che fungerà da identificatore pubblico univoco di tale hash (allo stesso modo in cui l'accesso è un identificativo pubblico della password hash del server). Il server restituirebbe l'hash per questo id e il client sarà in grado di password_verify utilizzando l'e-mail che conosce (quindi l'e-mail non viene trasferita, ma l'hash è).

    
risposta data 03.07.2018 - 14:10
fonte

Leggi altre domande sui tag