Перейти к основному содержанию
Change page

Определение секретного хранилища Web3

Последнее обновление страницы: 21 октября 2025 г.

Чтобы ваше приложение работало на Ethereum, вы можете использовать объект web3, предоставляемый библиотекой web3.js. Под капотом он взаимодействует с локальным узлом через вызовы RPC. web3opens in a new tab работает с любым узлом Ethereum, который предоставляет уровень RPC.

web3 содержит объект eth — web3.eth.

1var fs = require("fs")
2var recognizer = require("ethereum-keyfile-recognizer")
3
4fs.readFile("keyfile.json", (err, data) => {
5 var json = JSON.parse(data)
6 var result = recognizer(json)
7})
8
9/** result
10 * [ 'web3', 3 ] файл ключей web3 (v3)
11 * [ 'ethersale', undefined ] файл ключей Ethersale
12 * null недействительный файл ключей
13 */
Показать все

Этот документ описывает версию 3 определения секретного хранилища Web3.

Определение

Фактическое кодирование и декодирование файла в значительной степени не изменилось по сравнению с версией 1, за исключением того, что криптоалгоритм больше не привязан к AES-128-CBC (теперь минимальным требованием является AES-128-CTR). Большинство значений/алгоритм похожи на версию 1, за исключением mac, который задается как SHA3 (keccak-256) от конкатенации вторых слева 16 байт производного ключа вместе с полным ciphertext.

Файлы секретных ключей хранятся непосредственно в ~/.web3/keystore (для Unix-подобных систем) и ~/AppData/Web3/keystore (для Windows). Им можно давать любые имена, но хорошим соглашением является <uuid>.json, где <uuid> — это 128-битный UUID, присвоенный секретному ключу (прокси, сохраняющий конфиденциальность, для адреса секретного ключа).

Все такие файлы имеют связанный с ними пароль. Чтобы получить секретный ключ из заданного .json-файла, сначала получите ключ шифрования файла; это делается путем получения пароля файла и его передачи через функцию получения ключа, как описано ключом kdf. Статические и динамические параметры, зависящие от KDF, для функции KDF описаны в ключе kdfparams.

PBKDF2 должен поддерживаться всеми минимально совместимыми реализациями, что обозначается через:

  • kdf: pbkdf2

Для PBKDF2 kdfparams включают:

  • prf: должен быть hmac-sha256 (может быть расширен в будущем);
  • c: количество итераций;
  • salt: соль, передаваемая в PBKDF;
  • dklen: длина производного ключа. Должно быть >= 32.

После получения ключа файла его следует проверить путем выведения MAC. MAC должен быть вычислен как хэш SHA3 (keccak-256) массива байтов, образованного путем конкатенации вторых слева 16 байт производного ключа с содержимым ключа ciphertext, т. е.:

1KECCAK(DK[16..31] ++ <ciphertext>)

(где ++ — это оператор конкатенации)

Это значение следует сравнить с содержимым ключа mac; если они отличаются, следует запросить другой пароль (или отменить операцию).

После проверки ключа файла шифротекст (ключ ciphertext в файле) может быть расшифрован с помощью алгоритма симметричного шифрования, указанного ключом cipher и параметризованного через ключ cipherparams. Если размер производного ключа и размер ключа алгоритма не совпадают, в качестве ключа для алгоритма следует использовать крайние правые байты производного ключа, дополненные нулями.

Все минимально совместимые реализации должны поддерживать алгоритм AES-128-CTR, что обозначается через:

  • cipher: aes-128-ctr

Этот шифр принимает следующие параметры, указанные в качестве ключей для ключа cipherparams:

  • iv: 128-битный вектор инициализации для шифра.

Ключ для шифра представляет собой крайние левые 16 байт производного ключа, т. е. DK[0..15]

Создание/шифрование секретного ключа должно быть, по сути, обратным этим инструкциям. Убедитесь, что uuid, salt и iv действительно случайны.

В дополнение к полю version, которое должно выступать в качестве «жесткого» идентификатора версии, реализации могут также использовать minorversion для отслеживания небольших, некритичных изменений в формате.

Тестовые векторы

Подробности:

  • Адрес: 008aeeda4d805471df9b2a5b0f38a0c3bcba786b
  • ICAP: XE542A5PZHH8PYIZUBEJEO0MFWRAPPIL67
  • UUID: 3198bc9c-6672-5ab3-d9954942343ae5b6
  • Пароль: testpassword
  • Секрет: 7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d

PBKDF2-SHA-256

Тестовый вектор с использованием AES-128-CTR и PBKDF2-SHA-256:

Содержимое файла ~/.web3/keystore/3198bc9c-6672-5ab3-d9954942343ae5b6.json:

1{
2 "crypto": {
3 "cipher": "aes-128-ctr",
4 "cipherparams": {
5 "iv": "6087dab2f9fdbbfaddc31a909735c1e6"
6 },
7 "ciphertext": "5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46",
8 "kdf": "pbkdf2",
9 "kdfparams": {
10 "c": 262144,
11 "dklen": 32,
12 "prf": "hmac-sha256",
13 "salt": "ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd"
14 },
15 "mac": "517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2"
16 },
17 "id": "3198bc9c-6672-5ab3-d995-4942343ae5b6",
18 "version": 3
19}
Показать все

Промежуточные значения:

Производный ключ: f06d69cdc7da0faffb1008270bca38f5e31891a3a773950e6d0fea48a7188551 Тело MAC: e31891a3a773950e6d0fea48a71885515318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46 MAC: 517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2 Ключ шифра: f06d69cdc7da0faffb1008270bca38f5

Scrypt

Тестовый вектор с использованием AES-128-CTR и Scrypt:

1{
2 "crypto": {
3 "cipher": "aes-128-ctr",
4 "cipherparams": {
5 "iv": "740770fce12ce862af21264dab25f1da"
6 },
7 "ciphertext": "dd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2",
8 "kdf": "scrypt",
9 "kdfparams": {
10 "dklen": 32,
11 "n": 262144,
12 "p": 1,
13 "r": 8,
14 "salt": "25710c2ccd7c610b24d068af83b959b7a0e5f40641f0c82daeb1345766191034"
15 },
16 "mac": "337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c"
17 },
18 "id": "3198bc9c-6672-5ab3-d995-4942343ae5b6",
19 "version": 3
20}
Показать все

Промежуточные значения:

Производный ключ: 7446f59ecc301d2d79bc3302650d8a5cedc185ccbb4bf3ca1ebd2c163eaa6c2d Тело MAC: edc185ccbb4bf3ca1ebd2c163eaa6c2ddd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2 MAC: 337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c Ключ шифра: 7446f59ecc301d2d79bc3302650d8a5c

Изменения по сравнению с версией 1

Эта версия исправляет несколько несоответствий с версией 1, опубликованной здесьopens in a new tab. Вкратце это:

  • Использование заглавных букв необоснованно и непоследовательно (scrypt в нижнем регистре, Kdf в смешанном регистре, MAC в верхнем регистре).
  • Адрес не является необходимым и нарушает конфиденциальность.
  • Salt по своей сути является параметром функции получения ключа и заслуживает того, чтобы быть связанным с ней, а не с криптографией в целом.
  • SaltLen не является необходимым (просто получите его из Salt).
  • Функция получения ключа задана, однако криптографический алгоритм жестко задан.
  • Version по своей сути является числом, но при этом является строкой (структурированное управление версиями было бы возможно со строкой, но это можно считать выходящим за рамки редко меняющегося формата файла конфигурации).
  • KDF и cipher условно являются родственными понятиями, но организованы по-разному.
  • MAC вычисляется с помощью данных, не зависящих от пробелов (!)

В формат были внесены изменения, чтобы получить следующий файл, функционально эквивалентный примеру, приведенному на ранее упомянутой странице:

1{
2 "crypto": {
3 "cipher": "aes-128-cbc",
4 "ciphertext": "07533e172414bfa50e99dba4a0ce603f654ebfa1ff46277c3e0c577fdc87f6bb4e4fe16c5a94ce6ce14cfa069821ef9b",
5 "cipherparams": {
6 "iv": "16d67ba0ce5a339ff2f07951253e6ba8"
7 },
8 "kdf": "scrypt",
9 "kdfparams": {
10 "dklen": 32,
11 "n": 262144,
12 "p": 1,
13 "r": 8,
14 "salt": "06870e5e6a24e183a5c807bd1c43afd86d573f7db303ff4853d135cd0fd3fe91"
15 },
16 "mac": "8ccded24da2e99a11d48cda146f9cc8213eb423e2ea0d8427f41c3be414424dd",
17 "version": 1
18 },
19 "id": "0498f19a-59db-4d54-ac95-33901b4f1870",
20 "version": 2
21}
Показать все

Изменения по сравнению с версией 2

Версия 2 была ранней реализацией на C++ с рядом ошибок. Все основные элементы остались без изменений.

Была ли эта статья полезной?