You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于EthersJs与ReactNative实现类MetaMask的密码保护HD钱包

为HD钱包添加密码保护(React Native + Ethers.js)

核心逻辑

密码保护的核心是加密存储HD钱包的助记词/私钥,登录时通过密码解密恢复钱包——和MetaMask的思路一致,绝不明文存储任何敏感信息。

实现步骤

1. 依赖准备

先安装必要的库:

npm install react-native-keychain ethers
  • react-native-keychain:React Native官方推荐的安全存储工具,用于加密存储敏感数据
  • ethers.js:处理HD钱包生成、加密解密逻辑

2. 加密助记词(创建钱包时执行)

生成HD钱包后,用用户设置的密码加密助记词,再存入Keychain:

import { ethers } from 'ethers';
import * as Keychain from 'react-native-keychain';

// 加密并存储助记词
const encryptAndSaveMnemonic = async (mnemonic, password) => {
  // 基于密码生成加密密钥(PBKDF2慢哈希算法,防暴力破解)
  const salt = ethers.randomBytes(16);
  const encryptionKey = await ethers.pbkdf2(password, salt, 100000, 32, 'sha256');
  
  // AES加密助记词
  const iv = ethers.randomBytes(16);
  const encryptedMnemonic = ethers.AES.encrypt(mnemonic, encryptionKey, { iv }).toString();
  
  // 将加密所需的salt、iv和密文存入Keychain
  await Keychain.setGenericPassword(
    'encrypted_wallet',
    JSON.stringify({
      salt: salt.toString('hex'),
      iv: iv.toString('hex'),
      ciphertext: encryptedMnemonic
    }),
    { accessible: Keychain.ACCESSIBLE.WHEN_UNLOCKED }
  );
};

// 调用示例:生成HD钱包后加密存储
const createWallet = async (password) => {
  const mnemonic = ethers.Wallet.createRandom().mnemonic.phrase;
  await encryptAndSaveMnemonic(mnemonic, password);
  // 强制提示用户手动抄写助记词备份,APP内禁止留存任何备份副本
};

3. 解密登录(用户输入密码时执行)

从Keychain取出加密数据,用密码解密得到助记词,恢复HD钱包:

import { ethers } from 'ethers';
import * as Keychain from 'react-native-keychain';

// 解密并恢复钱包
const decryptAndRestoreWallet = async (password) => {
  try {
    // 从Keychain获取加密数据
    const credentials = await Keychain.getGenericPassword('encrypted_wallet');
    if (!credentials) throw new Error('未找到钱包数据');
    
    const { salt, iv, ciphertext } = JSON.parse(credentials.password);
    
    // 用密码重新生成密钥
    const encryptionKey = await ethers.pbkdf2(password, Buffer.from(salt, 'hex'), 100000, 32, 'sha256');
    
    // AES解密助记词
    const mnemonic = ethers.AES.decrypt(ciphertext, encryptionKey, { iv: Buffer.from(iv, 'hex') }).toString();
    
    // 恢复HD钱包
    const wallet = ethers.HDNodeWallet.fromPhrase(mnemonic);
    return wallet;
  } catch (error) {
    throw new Error('密码错误或钱包数据损坏');
  }
};

// 调用示例:登录时验证密码并恢复钱包
const handleLogin = async (password) => {
  try {
    const wallet = await decryptAndRestoreWallet(password);
    // 钱包恢复成功,进入主界面
  } catch (err) {
    // 提示用户密码错误或钱包不存在
    alert(err.message);
  }
};

4. 关键注意事项

  • 禁止明文存储:助记词、私钥永远不能以明文形式存在本地存储或内存中,用完及时清理相关变量
  • 密码强度校验:创建/登录时必须要求密码长度≥8位,且包含大小写、数字或特殊字符,避免弱密码
  • 安全存储配置:Keychain的accessible参数建议设为WHEN_UNLOCKED,确保只有设备解锁时才能访问加密数据
  • 错误模糊处理:解密失败时只提示“密码错误”,不要泄露具体错误信息,防止攻击者利用

内容的提问来源于stack exchange,提问作者An droid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 16:07:08