Как расшифровать keystore Ethereum, BNB и Polygon
Как с помощью PHP расшифровать приватный ключ из keystore-файла Ethereum, BNB или Polygon — пошаговое руководство в блоге Chaingateway.
Введение
Ethereum, Binance Smart Chain (BSC) и другие EVM-совместимые сети используют keystore-файлы для защиты приватных ключей пользователей. Keystore-файл — это JSON-файл, содержащий зашифрованный приватный ключ, защищённый паролем. По соображениям безопасности приложения часто хранят только keystore-файл, а не приватный ключ в открытом виде.
В этой статье блога мы покажем, как можно восстановить приватный ключ из keystore-файла с помощью PHP. Это особенно полезно, когда вам нужно экспортировать или восстановить свой приватный ключ для использования в другом приложении.
Предупреждение
Непосредственная работа с приватными ключами может быть рискованной, если не выполняется безопасным образом. Всегда убеждайтесь, что ваша среда безопасна, и избегайте излишнего раскрытия своего приватного ключа.
Понимание структуры keystore
Типичный keystore-файл — это JSON-объект, содержащий зашифрованную информацию о приватном ключе. Вот обзор ключевых разделов файла:
crypto: Содержит информацию, связанную с шифрованием.ciphertext: Зашифрованный приватный ключ.cipher: Алгоритм шифрования, используемый для шифрования.cipherparams: Содержит вектор инициализации (iv), используемый в процессе шифрования.kdf: Функция деривации ключа (KDF),pbkdf2илиscrypt, используемая для получения ключа шифрования из вашего пароля.kdfparams: Параметры для KDF, такие как соль, количество итераций (c) и длина ключа (dklen).mac: Код аутентификации сообщения, используемый для проверки успешности деривации ключа.
Как извлечь приватный ключ
Предварительные требования
Для извлечения приватного ключа из keystore-файла вам понадобятся следующие расширения PHP:
- php-json: Для парсинга keystore-файла (поскольку он представлен в формате JSON).
- php-openssl: Требуется для расшифровки приватного ключа (поскольку keystore-файлы используют AES-128-CTR для шифрования).
- php-scrypt: Требуется, если keystore использует KDF
scrypt. Подробнее здесь
Установите эти расширения с помощью:
sudo apt-get install php-json php-opensslsudo pecl install scryptВам также понадобятся:
- Содержимое keystore-файла.
- Пароль, использованный для защиты keystore.
1. Загрузка keystore и пароля
Начните с загрузки содержимого keystore-файла в массив PHP и определения пароля, который будет использоваться для расшифровки приватного ключа:
// 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. Извлечение данных шифрования
Данные шифрования хранятся в разделе crypto JSON-объекта 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'];3. Деривация ключа
Далее выведите ключ из пароля с помощью указанной KDF (pbkdf2 или scrypt). Keystore-файлы Ethereum обычно используют одну из этих двух KDF.
Для PBKDF2:
if ($kdf === 'pbkdf2') { $derivedKey = hash_pbkdf2( 'sha256', $password, hex2bin($salt), $kdfparams['c'], // iterations $kdfparams['dklen'] * 2, false );}Для Scrypt:
Если keystore использует KDF scrypt, вам понадобится расширение php-scrypt из перечисленных выше предварительных требований (pecl install scrypt). Оно реализует scrypt с теми же параметрами N/r/p, которые указаны в файле keystore, и, как и hash_pbkdf2() выше, по умолчанию возвращает производный ключ в виде шестнадцатеричной строки:
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. Проверка MAC
Перед расшифровкой приватного ключа проверьте, что MAC (код аутентификации сообщения) совпадает. Это гарантирует, что деривация ключа прошла успешно.
$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. Расшифровка приватного ключа
Если MAC совпадает, вы можете расшифровать приватный ключ с помощью выведенного ключа. В keystore-файлах Ethereum приватный ключ зашифрован с помощью шифра AES-128-CTR.
$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);На этом этапе вы должны успешно расшифровать и вывести приватный ключ.
Подведём итог
Мы рассмотрели шаги по извлечению приватного ключа из keystore-файла с помощью PHP. Загружая keystore, выводя ключ шифрования, проверяя MAC и расшифровывая приватный ключ, мы можем безопасно восстановить приватный ключ. Ниже приведён полный пример кода, обобщающий весь процесс.
Полный пример кода
<?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 formatecho 'Private key: ' . bin2hex($privateKey);Представляем наш бесплатный инструмент
Если вы ищете простой и полностью офлайн способ расшифровки keystore-файлов, ознакомьтесь с нашим бесплатным инструментом, доступным по адресу наш инструмент Keystore Decryptor.
Этот инструмент работает полностью офлайн, давая вам уверенность в работе с чувствительными данными приватного ключа без какого-либо подключения к интернету. Для обеспечения абсолютной безопасности вы можете отключить компьютер от интернета во время использования инструмента, гарантируя, что никакая чувствительная информация не будет раскрыта.
Вы также можете скачать его в нашем репозитории Github
Готовы собрать это сами? Получите свой API-ключ — 7-дневный пробный период, без карты — или посмотрите API блокчейна для полного справочника по эндпоинтам.