Autenticazione utente + crittografia del database con la stessa password

3

Sto lavorando a un progetto privato in cui ho bisogno di memorizzare i dati finanziari di un utente in un database. Cripteremo questi dati usando AES, e userò scrypt per generare una chiave di crittografia AES da una password utente più semplice.

Desidero anche essere in grado di comunicare all'utente se sta utilizzando la password corretta durante l'accesso. La velocità non è un problema: il programma verrà eseguito sul dispositivo dell'utente e non su un server multi-utente.

Quindi riassumendo: voglio utilizzare una sola password per crittografare i dati e autenticare gli utenti.

Posso vedere due opzioni per fare ciò:

  1. Genera un hash SHA-256 dall'output di scrypt, archivia l'hash in StoredHash e controlla se SHA256 (scrypt ("password fornita")) == StoredHash.

  2. Encrypt the scrypt-output della password usando AES in EncryptedScryptOutput usando scrypt-output come chiave e memorizzalo, e controlla se scrypt ("password fornita") == AESdescrypt (decryptionKey = scrypt ("fornito password "), EncryptedScryptOutput).

I (penso che io :-) sono consapevole del modo in cui questo dovrebbe essere fatto, usando sali e / o vettori iniziali. Le mie domande sono: ho corretto che entrambe le versioni saranno sicure? Diresti che una opzione è migliore dell'altra e perché?

Grazie!

    
posta Jelle Veraa 08.11.2012 - 11:53
fonte

2 risposte

3

Entrambe le opzioni sono sicure ma la prima è preferibile.

La tua prima proposta è di usare scrypt(password) come chiave di crittografia e SHA256(scrypt(password)) come verificatore di password. Questo va bene. Dal momento che non è calcolabile calcolarlo con una pre-immagine SHA256, non è possibile per un utente malintenzionato calcolare la chiave di crittografia dal verificatore della password.

La tua seconda proposta è di usare scrypt(password) come chiave di crittografia e di usare AES(scrypt(password), scrypt(password)) come verificatore della password. L'utilizzo di un valore come chiave per crittografare se stesso è una forma di hash, quindi questo è equivalente alla tua prima proposta, tranne che stai usando AES (x, x) per hash scrypt(password) invece di usare SHA256. Poiché SHA256 è una funzione di hash corretta e AES (x, x) non è la tua prima proposta è preferibile.

    
risposta data 08.11.2012 - 21:45
fonte
6

Per quanto ne so, lo schema è questo:

  • Calcola scrypt(pass) e memorizzalo come chiave di autenticazione nel tuo database.
  • Calcola sha256(scrypt(pass)) e utilizzalo come chiave di crittografia dei dati.

Il problema con questa tecnica è che un utente malintenzionato con accesso al tuo database può semplicemente calcolare l'hash SHA256 degli hash dello scrypt per ottenere le chiavi di crittografia.

Una soluzione migliore sarebbe utilizzare un secondo hash di scrypt come chiave di crittografia dei dati, con una chiave surrogata per facilitare le facili modifiche della password:

  • Genera due sali ( s1 e s2 ) e li memorizza in testo semplice.
  • Genera una chiave casuale protetta da crittografia k - questa è la nostra chiave surrogata.
  • Calcola scrypt(pass, s1) e memorizzalo come chiave di autenticazione nel tuo database.
  • Calcola scrypt(pass, s2) e xor k con esso. Memorizza questo valore nel tuo database.
  • Utilizza "k" come chiave di crittografia dei dati.

Durante la decrittografia, calcoli scrypt(pass, s2) e xo con il valore della chiave memorizzata per ottenere il valore originale di k indietro.

Questo ti protegge dai casi in cui il database è violato e ti permette di cambiare le password calcolando il valore originale di k , quindi lo sdoppia con l'hash scrypt della nuova password e salt. Tieni presente che se un utente dimentica la propria password, non sarà in grado di recuperare i dati.

    
risposta data 08.11.2012 - 13:37
fonte

Leggi altre domande sui tag