Блог
10 мин чтения
|
18 окт. 2024 г.

Как расшифровать keystore Ethereum, BNB и Polygon

Как с помощью PHP расшифровать приватный ключ из keystore-файла Ethereum, BNB или Polygon — пошаговое руководство в блоге Chaingateway.

Главы
C
Chaingateway Team
Эксперты по блокчейну

Введение

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:

  1. php-json: Для парсинга keystore-файла (поскольку он представлен в формате JSON).
  2. php-openssl: Требуется для расшифровки приватного ключа (поскольку keystore-файлы используют AES-128-CTR для шифрования).
  3. php-scrypt: Требуется, если keystore использует KDF scrypt. Подробнее здесь

Установите эти расширения с помощью:

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

Вам также понадобятся:

  1. Содержимое keystore-файла.
  2. Пароль, использованный для защиты 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 format
echo 'Private key: ' . bin2hex($privateKey);

Представляем наш бесплатный инструмент

Если вы ищете простой и полностью офлайн способ расшифровки keystore-файлов, ознакомьтесь с нашим бесплатным инструментом, доступным по адресу наш инструмент Keystore Decryptor.

Этот инструмент работает полностью офлайн, давая вам уверенность в работе с чувствительными данными приватного ключа без какого-либо подключения к интернету. Для обеспечения абсолютной безопасности вы можете отключить компьютер от интернета во время использования инструмента, гарантируя, что никакая чувствительная информация не будет раскрыта.

Вы также можете скачать его в нашем репозитории Github

Готовы собрать это сами? Получите свой API-ключ — 7-дневный пробный период, без карты — или посмотрите API блокчейна для полного справочника по эндпоинтам.

C
Chaingateway Team
Эксперты по блокчейну

Команда Chaingateway стремится упростить интеграцию блокчейна для разработчиков по всему миру.