Sfondo
Nell'articolo Come hackerare KeePass , l'autore ha usato keepass2john su un database KeePass per estrarre un hash della sua password principale.
Per il database CrackThis.kdb
l'hash estratto era (interruzioni di riga aggiunte da me)
$keepass$*
1*
6000*
0*
dfb86938fedd22b8235c4de4b02e5bb3*
c292fa502cbb0e912f30c1e1b6829a2c04ebe30477cb269d462fbbbeeb9360a6*
b85fb0e07f3edbd4123db2c829b79355*
6d4857a728900d4da4fad66999233e5c647e5354330d31be3a47bbdd102a5ca7*
0*
CrackThis
Quale hash viene effettivamente memorizzato?
Per comprendere i rischi di archiviare un tale hash, dobbiamo sapere di più sull'hash. Come viene calcolato e qual è stato l'input? Quali sono i diversi valori separati da *
?
Dal sito Web di KeePass ho appreso che KeePass esegue qualcosa come la seguente routine.
var password = readPasswordFromUser();
var hash1 = SHA256(password);
var salt = getSaltFromDatabase();
var iterations = getIterationsFromDatabase(); // default 6'000
var hash2 = AES_KDF(hash1, salt, iterations); // key derivation function
Il database viene quindi crittografato / decodificato utilizzando AES con la chiave hash2
.
Torna al nostro hash estratto dall'alto. Ci sono tre possibilità.
-
L'hash memorizzato / estratto è
hash2
. Poichéhash2
è usato come chiave di decodifica, questo sarebbe un disastro. Penso che possiamo escludere questo. -
L'hash memorizzato / estratto è
hash1
. Memorizzarehash1
rende inutile la funzione di derivazione della chiave (KDF). Il KDF è lì per rallentare gli attacchi bruteforce. Conhash1
un utente malintenzionato non ha a che fare con il KDF lento, ma solo con SHA256. -
Ho frainteso qualcosa e l'hash estratto non è né
hash1
néhash2
.
Domanda principale
Perché il database KeePass contiene un hash non criptato della sua password principale? Per decifrare il database non abbiamo bisogno di un hash, semplicemente decifriamo usando una password specifica. Se la password è sbagliata, i dati crittografati non hanno senso, nessun problema.
Se l'hash memorizzato è lì solo per evitare di trattare dati senza senso quando l'utente ha inserito una password errata per errore, allora non capisco perché non hanno usato un modo meno rischioso. Ad esempio, non sarebbe più sicuro calcolare un checksum (non necessariamente crittografico, ad esempio CRC) del database e crittografare il checksum + database. Sulla decrittografia, il checksum può essere verificato rispetto al database.