Fondo
En el artículo Cómo hackear KeePass , el autor usó keepass2john en una base de datos KeePass para extraer un hash de su contraseña maestra.
Para la base de datos CrackThis.kdb
, el hash extraído (saltos de línea agregados por mí)
$keepass$*
1*
6000*
0*
dfb86938fedd22b8235c4de4b02e5bb3*
c292fa502cbb0e912f30c1e1b6829a2c04ebe30477cb269d462fbbbeeb9360a6*
b85fb0e07f3edbd4123db2c829b79355*
6d4857a728900d4da4fad66999233e5c647e5354330d31be3a47bbdd102a5ca7*
0*
CrackThis
¿Qué hash está realmente almacenado?
Para comprender los riesgos de almacenar tal hash, tenemos que saber más sobre el hash. ¿Cómo se calcula y cuál fue la entrada? ¿Cuáles son los diferentes valores separados por *
?
De la sitio web de KeePass aprendí que KeePass ejecuta algo como la siguiente rutina.
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
La base de datos se encripta / desencripta utilizando AES con la clave hash2
.
Volver a nuestro hash extraído desde arriba. Hay tres posibilidades.
-
El hash almacenado / extraído es
hash2
. Comohash2
se usa como clave de descifrado, esto sería un desastre. Creo que podemos excluir este. -
El hash almacenado / extraído es
hash1
. El almacenamiento dehash1
hace que la función de derivación de claves (KDF) sea inútil. El KDF está ahí para frenar los ataques de fuerza bruta. Conhash1
, un atacante no tiene que lidiar con el KDF lento, sino solo con SHA256. -
Entendí mal algo y el hash extraído no es
hash1
nihash2
.
Pregunta principal
¿Por qué la base de datos KeePass contiene un hash no cifrado de su contraseña maestra? Para descifrar la base de datos no necesitamos un hash, simplemente desciframos con una contraseña determinada. Si la contraseña es incorrecta, los datos cifrados no tendrán sentido, no hay problema.
Si el hash almacenado solo está allí para evitar tratar con datos sin sentido cuando el usuario ingresó una contraseña incorrecta por accidente, entonces no entiendo por qué no utilizaron un método menos riesgoso. Por ejemplo, ¿no sería más seguro calcular una suma de comprobación (no necesariamente criptográfica, por ejemplo, CRC) de la base de datos y cifrar la suma de comprobación + la base de datos? En el descifrado, la suma de verificación se puede verificar en la base de datos.