ETH中的Web3密钥存储定义


Web3密钥存储定义规范了一种标准化的方法,用于加密和存储以太坊私钥,主要由钱包软件(如 MetaMask、Geth)使用。本文档将详细介绍其背景、文件结构、加密与解密流程,以及代码示例。


1. 背景与目的

1.1 什么是 Web3 密钥存储?

定义:Web3 密钥存储是一种 JSON 格式的文件规范,用于安全存储以太坊账户的私钥。

目的

  • 保护私钥免受未经授权的访问。
  • 便于跨钱包软件移植私钥。

使用场景

  • 用户通过密码加密私钥,生成密钥存储文件。
  • 钱包软件(如 Geth)读取文件,解密后访问私钥。

1.2 历史背景

  • 起源:由以太坊社区提出,最初用于 Geth 客户端。
  • 标准化:现已成为以太坊生态中的事实标准,许多钱包软件(如 MetaMask、MyEtherWallet)遵循该规范。

2. 密钥存储文件结构

2.1 JSON 格式

  • 文件扩展名:通常为 .json
  • 典型文件名UTC--YYYY-MM-DDTHH:MM:SS.SSSZ--<UUID>
    • UTC 时间戳:文件创建时间。
    • UUID:唯一标识。

2.2 JSON 字段解析

以下是密钥存储文件的核心字段:

{
  "version": 3,
  "id": "7e41e9e1-b477-44e2-a6ae-be50625b0a8f",
  "address": "aa8fb2d7630a64715577e399ff3ed5f5c4938389",
  "crypto": {
    "ciphertext": "d2b4bf81bd0c7ebbcfde07c8d4f3057f5405eabf897f0a01566a3fb9",
    "cipherparams": {
      "iv": "c22c0d01e5f11ac2ea6ddd78e2578f22"
    },
    "cipher": "aes-128-ctr",
    "kdf": "scrypt",
    "kdfparams": {
      "dklen": 32,
      "salt": "c3b875d218ca0e0eafe0e561a31747f6e735f7e0bc9d3a0aa1f7ec22c10e65de",
      "n": 8192,
      "r": 8,
      "p": 1
    },
    "mac": "f123d0ae24dde42f07a2512c54f0d69191577ae8fb1ab92b6a5f1e64f0d9e5e8"
  }
}

字段解析

  • version:当前版本为 3
  • id:唯一标识该密钥存储文件。
  • address:以太坊账户地址(无 0x 前缀)。
  • crypto:包含加密相关数据。
    • ciphertext:加密的私钥。
    • cipherparams.iv:初始化向量。
    • cipher:加密算法(如 aes-128-ctr)。
    • kdf:密钥派生函数(如 scryptpbkdf2)。
    • mac:消息认证码,确保数据完整性。

3. 加密与解密流程

3.1 加密流程

  1. 用户输入密码
  2. 密钥派生:使用 KDF(如 scrypt)从密码生成密钥。
  3. 加密私钥
    • 取派生密钥前 16 字节进行 AES-128-CTR 加密。
    • 生成 ciphertext
  4. 生成 MAC
    mac = keccak256(derived_key[16:32] || ciphertext)
  5. 保存 JSON 文件

3.2 解密流程

  1. 读取 JSON 文件
  2. 密钥派生:根据 kdfparams 重新生成 derived_key
  3. 验证 MAC,确保数据未被篡改。
  4. 解密私钥

4. 代码示例

4.1 生成密钥存储文件(JavaScript)

const password = "your_password_here";
const privateKey = "your_private_key_in_hex";
const salt = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);

const kdfParams = { n: 8192, r: 8, p: 1, dklen: 32 };
const derivedKey = scrypt(password, salt, kdfParams.n, kdfParams.r, kdfParams.p, kdfParams.dklen);

const cipherKey = derivedKey.slice(0, 16);
const cipher = crypto.createCipheriv('aes-128-ctr', cipherKey, iv);
const ciphertext = Buffer.concat([cipher.update(privateKey, 'hex'), cipher.final()]);

const mac = keccak256(Buffer.concat([derivedKey.slice(16, 32), ciphertext]));

4.2 解密密钥存储文件

const keystore = JSON.parse(fs.readFileSync('keystore.json'));
const { crypto } = keystore;
const derivedKey = scrypt(password, Buffer.from(crypto.kdfparams.salt, 'hex'), ...);

const computedMac = keccak256(Buffer.concat([derivedKey.slice(16, 32), Buffer.from(crypto.ciphertext, 'hex')]));
if (!computedMac.equals(Buffer.from(crypto.mac, 'hex'))) throw new Error('Invalid password');

const cipherKey = derivedKey.slice(0, 16);
const decipher = crypto.createDecipheriv('aes-128-ctr', cipherKey, Buffer.from(crypto.cipherparams.iv, 'hex'));
const privateKey = Buffer.concat([decipher.update(Buffer.from(crypto.ciphertext, 'hex')), decipher.final()]);

5. 安全性与注意事项

5.1 安全性特性

  • AES-128-CTR 提供强加密。
  • scrypt/PBKDF2 增加暴力破解难度。
  • MAC 机制 防止密文篡改。

5.2 注意事项

  • 使用强密码,防止被破解。
  • 合理设置 KDF 参数,如 n=8192 平衡安全性与性能。
  • 文件存储安全,避免泄露。

6. 总结

  • Web3 密钥存储 是一种标准化的私钥管理方案。
  • JSON 结构 规范化密钥存储方式。
  • 加密流程 采用 AES-128-CTR + KDF + MAC 保护私钥安全。
  • 代码示例 提供实现细节,方便开发者参考。

如需更深入探讨某部分(如优化 KDF 参数或 Rust 实现),请告诉我!


 上一篇
Solana概述 Solana概述
什么是 Solana?Solana是一个为大规模应用而构建的区块链。它是一个高性能网络,可用于一系列应用,包括金融、支付和游戏。Solana运行在一个独立的全球状态机,并且是开放的、可互操作的和去中心化的。 为什么选择 Solana?Sol
2025-03-08
下一篇 
ETH中的简单序列化 ETH中的简单序列化
简单序列化 (SSZ) 是信标链上使用的序列化方法。 这种方法取代了除对等点发现协议以外的共识层各处执行层上所用的递归长度前缀序列化。 简单序列化设计具有确定性,也可以有效地进行默克尔化。 可以认为,简单序列化有两个组成部分:序列化方案和默
2025-03-07
  目录