Визначення секретного сховища Web3
Щоб ваш застосунок працював в Етеріумі, ви можете використовувати об'єкт web3, який надає бібліотека Web3.js. Технічно він взаємодіє з локальним вузлом через RPC-виклики. web3 (opens in a new tab) працює з будь-яким вузлом Етеріуму, який відкриває доступ до рівня RPC.
web3 містить об'єкт eth — web3.eth.
var fs = require("fs")
var recognizer = require("ethereum-keyfile-recognizer")
fs.readFile("keyfile.json", (err, data) => {
var json = JSON.parse(data)
var result = recognizer(json)
})
/** результат
* [ 'web3', 3 ] файл ключа Web3 (v3)
* [ 'ethersale', undefined ] файл ключа Ethersale
* null недійсний файл ключа
*/
Цей документ описує версію 3 визначення секретного сховища Web3.
Визначення
Фактичне кодування та декодування файлу залишається переважно незмінним порівняно з версією 1, за винятком того, що криптоалгоритм більше не фіксується як AES-128-CBC (тепер мінімальною вимогою є AES-128-CTR). Більшість значень/алгоритмів подібні до версії 1, за винятком mac, який подається як SHA3 (Кеччак-256) від конкатенації других зліва 16 байтів похідного ключа разом із повним ciphertext.
Файли секретних ключів зберігаються безпосередньо в ~/.web3/keystore (для Unix-подібних систем) та ~/AppData/Web3/keystore (для Windows). Вони можуть мати будь-яку назву, але хорошою практикою є використання формату <uuid>.json, де <uuid> — це 128-бітний UUID, наданий секретному ключу (проксі-ідентифікатор для адреси секретного ключа, що зберігає приватність).
Усі такі файли мають пов'язаний пароль. Щоб отримати секретний ключ певного файлу .json, спочатку потрібно отримати ключ шифрування файлу; це робиться шляхом взяття пароля файлу та його передачі через функцію формування ключа (KDF), як описано в ключі kdf. Статичні та динамічні параметри, що залежать від KDF і передаються до функції KDF, описані в ключі kdfparams.
PBKDF2 має підтримуватися всіма мінімально сумісними реалізаціями, що позначається як:
kdf:pbkdf2
Для PBKDF2 параметри kdfparams включають:
prf: Має бутиhmac-sha256(може бути розширено в майбутньому);c: кількість ітерацій;salt: сіль, передана до PBKDF;dklen: довжина похідного ключа. Має бути >= 32.
Після того, як ключ файлу було отримано, його слід перевірити шляхом обчислення MAC. MAC має обчислюватися як хеш SHA3 (Кеччак-256) від масиву байтів, утвореного конкатенацією других зліва 16 байтів похідного ключа з вмістом ключа ciphertext, тобто:
KECCAK(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 для відстеження менших змін у форматі, що не порушують сумісність.
Тестові вектори
Деталі:
Address:008aeeda4d805471df9b2a5b0f38a0c3bcba786bICAP:XE542A5PZHH8PYIZUBEJEO0MFWRAPPIL67UUID:3198bc9c-6672-5ab3-d9954942343ae5b6Password:testpasswordSecret:7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d
PBKDF2-SHA-256
Тестовий вектор із використанням AES-128-CTR та PBKDF2-SHA-256:
Вміст файлу ~/.web3/keystore/3198bc9c-6672-5ab3-d9954942343ae5b6.json:
{
"crypto": {
"cipher": "aes-128-ctr",
"cipherparams": {
"iv": "6087dab2f9fdbbfaddc31a909735c1e6"
},
"ciphertext": "5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46",
"kdf": "pbkdf2",
"kdfparams": {
"c": 262144,
"dklen": 32,
"prf": "hmac-sha256",
"salt": "ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd"
},
"mac": "517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2"
},
"id": "3198bc9c-6672-5ab3-d995-4942343ae5b6",
"version": 3
}
Проміжні значення:
Derived key: f06d69cdc7da0faffb1008270bca38f5e31891a3a773950e6d0fea48a7188551
MAC Body: e31891a3a773950e6d0fea48a71885515318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46
MAC: 517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2
Cipher key: f06d69cdc7da0faffb1008270bca38f5
Scrypt
Тестовий вектор із використанням AES-128-CTR та Scrypt:
{
"crypto": {
"cipher": "aes-128-ctr",
"cipherparams": {
"iv": "740770fce12ce862af21264dab25f1da"
},
"ciphertext": "dd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2",
"kdf": "scrypt",
"kdfparams": {
"dklen": 32,
"n": 262144,
"p": 1,
"r": 8,
"salt": "25710c2ccd7c610b24d068af83b959b7a0e5f40641f0c82daeb1345766191034"
},
"mac": "337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c"
},
"id": "3198bc9c-6672-5ab3-d995-4942343ae5b6",
"version": 3
}
Проміжні значення:
Derived key: 7446f59ecc301d2d79bc3302650d8a5cedc185ccbb4bf3ca1ebd2c163eaa6c2d
MAC Body: edc185ccbb4bf3ca1ebd2c163eaa6c2ddd8a1132cf57db67c038c6763afe2cbe6ea1949a86abc5843f8ca656ebbb1ea2
MAC: 337aeb86505d2d0bb620effe57f18381377d67d76dac1090626aa5cd20886a7c
Cipher key: 7446f59ecc301d2d79bc3302650d8a5c
Зміни порівняно з версією 1
Ця версія виправляє кілька невідповідностей із версією 1, опублікованою тут (opens in a new tab). Коротко кажучи, це:
- Використання великих літер є невиправданим і непослідовним (scrypt з малої літери, Kdf зі змішаним регістром, MAC з великої літери).
- Адреса є непотрібною та ставить під загрозу приватність.
Saltза своєю суттю є параметром функції формування ключа і має бути пов'язаний з нею, а не з крипто загалом.- SaltLen є непотрібним (його можна просто отримати з Salt).
- Функція формування ключа задана, проте криптографічний алгоритм жорстко визначений.
Versionза своєю суттю є числовим значенням, але представлений як рядок (структуроване керування версіями було б можливим за допомогою рядка, але це можна вважати таким, що виходить за рамки формату конфігураційного файлу, який рідко змінюється).KDFтаcipherє концептуально спорідненими поняттями, проте організовані по-різному.MACобчислюється через фрагмент даних, що не залежить від пробілів(!)
До формату було внесено зміни, щоб отримати наступний файл, функціонально еквівалентний прикладу, наведеному на сторінці за посиланням вище:
{
"crypto": {
"cipher": "aes-128-cbc",
"ciphertext": "07533e172414bfa50e99dba4a0ce603f654ebfa1ff46277c3e0c577fdc87f6bb4e4fe16c5a94ce6ce14cfa069821ef9b",
"cipherparams": {
"iv": "16d67ba0ce5a339ff2f07951253e6ba8"
},
"kdf": "scrypt",
"kdfparams": {
"dklen": 32,
"n": 262144,
"p": 1,
"r": 8,
"salt": "06870e5e6a24e183a5c807bd1c43afd86d573f7db303ff4853d135cd0fd3fe91"
},
"mac": "8ccded24da2e99a11d48cda146f9cc8213eb423e2ea0d8427f41c3be414424dd",
"version": 1
},
"id": "0498f19a-59db-4d54-ac95-33901b4f1870",
"version": 2
}
Зміни порівняно з версією 2
Версія 2 була ранньою реалізацією на C++ із низкою помилок. Усі основні елементи залишилися незмінними порівняно з нею.