Funcion BytesToKeySHA512AES en el bitcoin

Iniciado por AlbertoBSD, 29 Octubre 2020, 15:26 PM

0 Miembros y 1 Visitante están viendo este tema.

AlbertoBSD

Recientemente publique el tema:Como determina la función AES256CBCDecrypt una correcta desencriptación El cual esta relacionado con este de forma algo indirecta.

Todo esto viene del análisis que estoy realizando al código fuente del Bitcoin Core.

Hoy hablaré sobre la función BytesToKeySHA512AES la cual es una de las primeras que se utilizan cuando intentas desbloquear una cartera bitcoin protegida con un passphrase.

BytesToKeySHA512AES básicamente toma las passphrase ingresada + un salt proporcionado por el mismo archivo wallet.dat y los transforma en un (key, iv) para posteriormente utilizarlos como material para descifrar la llave cifrada.

El código fuente de BytesToKeySHA512AES, lo pueden encontrar en

https://github.com/bitcoin/bitcoin/blob/master/src/wallet/crypter.cpp 

Tiene 3 parámetros de entrada y 2 de salida
Entrada:
Salt
Passphrase
Count

Salida:
Key
IV

La parte interesante del código es la siguiente:

Código (c++) [Seleccionar]
    for(int i = 0; i != count - 1; i++)
        di.Reset().Write(buf, sizeof(buf)).Finalize(buf);


Básicamente obtiene el hash sha512 de si mismo (count -1) veces ya la que primera vez fue el hash sha512 de (passphrase + IV) como muestra el siguiente código:

Código (c++) [Seleccionar]
    di.Write((const unsigned char*)strKeyData.data(), strKeyData.size());
    di.Write(chSalt.data(), chSalt.size());
    di.Finalize(buf);


Posteriormente copia los primeros 32 bytes al Key y los siguientes 16 bytes al Vector IV

Si no están familiarizados con la sintaxis  del codigo anterior dejare un código en PHP ejemplificando lo que hace la función:

Código (php) [Seleccionar]
<?php
$salt 
"BBBBBBBBBBBBBBBB";
$passphrase "AAAAA";
$key_ ="";
$iv_ "";
BytesToKeySHA512AES($salt ,$passphrase,2,$key_$iv_ );

echo 
"Key:\n";
var_dump($key_);
echo 
"IV:\n";
var_dump($iv_);

function 
BytesToKeySHA512AES($chSalt,$strKeyData,$count,&$key,&$iv) {
$ctx hash_init('sha512');
hash_update($ctx,$strKeyData);
hash_update($ctx,$chSalt);
$buf hash_final($ctx,true);
$i 0;
while($i != $count -1) {

/* //Estas tres líneas básicamente se transforman en una simple llamada a hash
$ctx = hash_init('sha512');
hash_update($ctx,$buf);
$buf = hash_final($ctx,true);
*/
$buf hash('sha512',$buf,true);
$i++;
}
echo "hash:\n";
var_dump($buf);
$key mb_substr($buf,0,32);
$iv mb_substr($buf,32,16);
}
?>


Lo escribí en PHP ya que es mas fácil darle seguimiento a las funciones hash, solo que no estoy 100% seguro de como manejar las copia de los bytes del hash resultante al key y al IV respectivamente.

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

kub0x

Básicamente tienes dos posibilidades,

bruteforcear el passhprase usando la PBKDF o bien bruteforcear la clave AES que resulta de la PBKDF. Supongo que esto ya lo sabes y es prácticamente imposible, pero bueno, ánimo que igual suena la flauta.

Saludos.
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


AlbertoBSD

Cita de: kub0x en 31 Octubre 2020, 15:22 PM
bruteforcear el passhprase usando la PBKDF o bien bruteforcear la clave AES que resulta de la PBKDF.

La primera opciones tienes que pasar por el proceso completo es decir generar un passphrase random de N cantidad de bytes que buen puede ser 1 byte o bien puede ser 1GB, posteriormente pasarlos por el PBKDF sha512 con un mínimo de 25000 iteraciones.

Yo se que la gente no mete passphrase de 1GB de longitud y también están limitadas por los caracteres fácilmente  localizables por el teclado sin embargo las mínimo 25K iteraciones del sha512 hacen el proceso un poco mas ineficientes para el crackeo desde el momento que cada passphrase random tiene que pasar por ese proceso.

La segunda opciones que mencionas es la que voy implementar ya que solo tienes que generar el KEY y el IV de forma aleatoria y pasalos a la función  AES256CBCDecrypt saltándose el costoso proceso de PBKDF.

Además esta opción esta claramente limitada por el tamaño de la dupla Key,IV y en la primera opción no voy a estar seguro si probe todas las combinaciones posibles en el passphrase además que un passphrase de mas 46 dígitos ya es mas costoso por que incluyen más posibilidades y el proceso del PBKDF.

Cita de: kub0x en 31 Octubre 2020, 15:22 PM
Supongo que esto ya lo sabes y es prácticamente imposible, pero bueno, ánimo que igual suena la flauta.

Si claro que se que es improbable, pero al final mi objetivo será encontrar el camino más eficiente para hacerlo, independientemente de su probabilidad.

Saludos!
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

Danielㅤ

La única ventaja clara que tenés actualmente es que vos sabés la contraseña, solo buscas saber el proceso de cifrado para proceder al descifrado.


Saludos
¡Regresando como cual Fenix! ~
Bomber Code © 2021 https://www.bombercode.net/foro/

Ayudas - Aportes - Tutoriales - Y mucho mas!!!