Blog
10 min de lectura
|
18 oct 2024

Cómo descifrar keystores de Ethereum, BNB y Polygon

Cómo descifrar con PHP la clave privada de un archivo keystore de Ethereum, BNB o Polygon, paso a paso, en el blog de Chaingateway.

Capítulos
C
Chaingateway Team
Expertos en blockchain

Introducción

Ethereum, Binance Smart Chain (BSC) y otras redes compatibles con EVM utilizan archivos keystore para proteger las claves privadas de los usuarios. Un archivo keystore es un archivo JSON que contiene una clave privada cifrada, protegida con una contraseña. Por motivos de seguridad, las aplicaciones a menudo almacenan solo el archivo keystore, no la clave privada en texto plano.

En esta entrada de blog, mostraremos cómo puede recuperar la clave privada de un archivo keystore utilizando PHP. Esto es especialmente útil cuando necesita exportar o recuperar su clave privada para usarla en otra aplicación.

Advertencia

Manejar directamente claves privadas puede ser arriesgado si no se hace de forma segura. Asegúrese siempre de que su entorno sea seguro y evite exponer innecesariamente su clave privada.

Entendiendo la estructura del keystore

Un archivo keystore típico es un objeto JSON que contiene información cifrada sobre la clave privada. Aquí tiene un resumen de las secciones clave del archivo:

  • crypto: Contiene información relacionada con el cifrado.
    • ciphertext: La clave privada cifrada.
    • cipher: El algoritmo de cifrado utilizado.
    • cipherparams: Contiene el vector de inicialización (iv) utilizado en el proceso de cifrado.
    • kdf: Función de derivación de clave (KDF), ya sea pbkdf2 o scrypt, utilizada para derivar la clave de cifrado a partir de su contraseña.
    • kdfparams: Parámetros para la KDF, como la sal, las iteraciones (c) y la longitud de clave (dklen).
    • mac: Código de autenticación de mensaje, utilizado para verificar que la derivación de clave se realizó correctamente.

Cómo extraer la clave privada

Requisitos previos

Para extraer una clave privada de un archivo keystore, necesitará las siguientes extensiones de PHP:

  1. php-json: Para analizar el archivo keystore (ya que está en formato JSON).
  2. php-openssl: Requerida para descifrar la clave privada (ya que los keystores usan AES-128-CTR para el cifrado).
  3. php-scrypt: Necesaria si el keystore usa la KDF scrypt. Más información aquí

Instale estas extensiones con:

Terminal window
sudo apt-get install php-json php-openssl
sudo pecl install scrypt

También necesitará:

  1. El contenido del archivo keystore.
  2. La contraseña que se utilizó para proteger el keystore.

1. Cargar el keystore y la contraseña

Comience cargando el contenido del archivo keystore en un array de PHP y definiendo la contraseña que se utilizará para descifrar la clave privada:

// Load keystore JSON file
$keystore = file_get_contents('/path/to/keystore-file.json');
$keystore_json = json_decode($keystore, true);
// Define the password
$password = "YOUR_PASSWORD";

2. Extraer los datos de cifrado

Los datos de cifrado se almacenan en la sección crypto del JSON del keystore. Necesitará extraer los campos relevantes para usarlos en el proceso de descifrado.

$crypto = $keystore_json['crypto'];
$ciphertext = $crypto['ciphertext'];
$iv = $crypto['cipherparams']['iv'];
$salt = $crypto['kdfparams']['salt'];
$kdf = $crypto['kdf'];
$kdfparams = $crypto['kdfparams'];
$mac = $crypto['mac'];

3. Derivar la clave

A continuación, derive la clave a partir de la contraseña utilizando la KDF especificada (pbkdf2 o scrypt). Los keystores de Ethereum suelen usar una de estas dos KDF.

Para PBKDF2:

if ($kdf === 'pbkdf2') {
$derivedKey = hash_pbkdf2(
'sha256',
$password,
hex2bin($salt),
$kdfparams['c'], // iterations
$kdfparams['dklen'] * 2,
false
);
}

Para Scrypt:

Si el keystore usa la KDF scrypt, necesitará la extensión php-scrypt de los prerrequisitos anteriores (pecl install scrypt). Implementa scrypt con los mismos parámetros N/r/p que especifica el archivo keystore y, al igual que hash_pbkdf2() anterior, devuelve la clave derivada como una cadena hexadecimal de forma predeterminada:

if ($kdf === 'scrypt') {
$N = $kdfparams['n'];
$r = $kdfparams['r'];
$p = $kdfparams['p'];
$dklen = $kdfparams['dklen'];
// Derive the key using the php-scrypt extension
$derivedKey = scrypt($password, hex2bin($salt), $N, $r, $p, $dklen);
}

4. Verificar el MAC

Antes de descifrar la clave privada, verifique que el MAC (Código de Autenticación de Mensaje) coincida. Esto garantiza que la derivación de clave se realizó correctamente.

$derivedKeyPart = substr($derivedKey, 0, 32);
$calculatedMac = hash('sha3-256', hex2bin(substr($derivedKey, 32)) . hex2bin($ciphertext));
if ($calculatedMac !== $mac) {
die('MAC verification failed. The password may be incorrect or the keystore may be corrupted.');
}

5. Descifrar la clave privada

Si el MAC coincide, puede descifrar la clave privada utilizando la clave derivada. La clave privada está cifrada con el cifrado AES-128-CTR en los keystores de Ethereum.

$privateKey = openssl_decrypt(
hex2bin($ciphertext),
'aes-128-ctr',
hex2bin($derivedKeyPart),
OPENSSL_RAW_DATA,
hex2bin($iv)
);
if (!$privateKey) {
die('Failed to decrypt the private key.');
}
echo 'Private key: ' . bin2hex($privateKey);

En este punto, debería haber descifrado e impreso correctamente la clave privada.

Para resumir

Hemos repasado los pasos para extraer una clave privada de un archivo keystore utilizando PHP. Al cargar el keystore, derivar la clave de cifrado, verificar el MAC y descifrar la clave privada, podemos recuperar la clave privada de forma segura. A continuación se muestra el ejemplo de código completo que resume todo el proceso.

Ejemplo de código completo

<?php
// Step 1: Load keystore JSON file
$keystore = file_get_contents('/path/to/keystore-file.json');
$keystore_json = json_decode($keystore, true);
// Step 2: Define the password
$password = "YOUR_PASSWORD";
// Step 3: Extract relevant data from the keystore
$crypto = $keystore_json['crypto'];
$ciphertext = $crypto['ciphertext'];
$iv = $crypto['cipherparams']['iv'];
$salt = $crypto['kdfparams']['salt'];
$kdf = $crypto['kdf'];
$kdfparams = $crypto['kdfparams'];
$mac = $crypto['mac'];
// Step 4: Derive the key based on the KDF used (pbkdf2 or scrypt)
if ($kdf === 'pbkdf2') {
// PBKDF2 key derivation
$derivedKey = hash_pbkdf2(
'sha256',
$password,
hex2bin($salt),
$kdfparams['c'], // iterations
$kdfparams['dklen'] * 2,
false
);
} elseif ($kdf === 'scrypt') {
// Scrypt key derivation (requires the php-scrypt PECL extension)
$N = $kdfparams['n'];
$r = $kdfparams['r'];
$p = $kdfparams['p'];
$dklen = $kdfparams['dklen'];
$derivedKey = scrypt($password, hex2bin($salt), $N, $r, $p, $dklen);
} else {
die('Unsupported KDF method.');
}
// Step 5: Verify the MAC
$derivedKeyPart = substr($derivedKey, 0, 32);
$calculatedMac = hash('sha3-256', hex2bin(substr($derivedKey, 32)) . hex2bin($ciphertext));
if ($calculatedMac !== $mac) {
die('MAC verification failed. Wrong password or corrupted keystore.');
}
// Step 6: Decrypt the private key
$privateKey = openssl_decrypt(
hex2bin($ciphertext),
'aes-128-ctr',
hex2bin($derivedKeyPart),
OPENSSL_RAW_DATA,
hex2bin($iv)
);
if (!$privateKey) {
die('Failed to decrypt the private key.');
}
// Output the private key in hexadecimal format
echo 'Private key: ' . bin2hex($privateKey);

Presentamos nuestra herramienta gratuita

Si está buscando una forma sencilla y totalmente sin conexión de descifrar archivos keystore, consulte nuestra herramienta gratuita disponible en nuestra herramienta Keystore Decryptor.

Esta herramienta funciona completamente sin conexión, brindándole la confianza para manejar sus datos sensibles de clave privada sin ninguna conexión a internet. Para garantizar una seguridad absoluta, puede desconectar su computadora de internet mientras usa la herramienta, garantizando que no se exponga ninguna información sensible.

También puede descargarla en nuestro repositorio de Github

¿Listo para construirlo tú mismo? Obtenga su clave de API — prueba de 7 días, sin tarjeta — o consulte API Blockchain para la referencia completa de los endpoints.

C
Chaingateway Team
Expertos en blockchain

El equipo de Chaingateway se dedica a simplificar la integración blockchain para desarrolladores de todo el mundo.