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

如何修复EthCrypto.js中的‘Bad MAC’解密错误?

Bad MAC错误原因及修复方案(EthCrypto.js加解密场景)

错误原因

Bad MAC错误本质是解密时生成的消息认证码与加密后存储的MAC不匹配,核心问题在于签名恢复公钥时使用的哈希值和前端personal.sign签名时的哈希值不一致:

  • Web3的personal.sign方法会自动给待签名消息添加固定前缀:\x19Ethereum Signed Message:\n${消息长度},再对拼接后的完整内容做Keccak256哈希后进行签名。
  • 你当前代码直接对原始消息'Signature verification for video file encryption'做Keccak256哈希,导致恢复出的公钥并非签名账户对应的正确公钥,用错误公钥加密的内容,用正确私钥解密必然触发MAC验证失败。

修复方案

需要在恢复公钥时,构造与personal.sign完全一致的带前缀消息,再计算哈希用于公钥恢复:

修正后的公钥恢复代码

const signature = '0x27b76aa76e75d3a723883629b532b771ec860edb338b0c8421244bbd1f3d0f7078eb7bd17aad73823b0d401e917e7edcc5ca267a34623f4c7e4b3cefbfab7ac31b';
const plaintext = 'test message';
const originalMessage = 'Signature verification for video file encryption';

// 构造personal.sign使用的带前缀消息
const prefixedMessage = `\x19Ethereum Signed Message:\n${originalMessage.length}${originalMessage}`;
// 计算带前缀消息的Keccak256哈希
const messageHash = EthCrypto.hash.keccak256(prefixedMessage);

// 用带前缀的哈希恢复正确公钥
const publicKey = EthCrypto.recoverPublicKey(signature, messageHash);

// 后续加密流程保持不变
const encrypted = await EthCrypto.encryptWithPublicKey(publicKey, plaintext);
return EthCrypto.cipher.stringify(encrypted);

额外验证点

  • 确认解密用的privateKey确实属于账户0x500694d00eFc0315Cac629b83Dfd11C8b038AfAa,可通过EthCrypto.publicKeyByPrivateKey(privateKey)生成公钥,与恢复出的公钥对比是否一致。
  • 确保加密对象字符串化和解析过程中没有丢失或篡改字段(如iv、ephemPublicKey、ciphertext、mac的格式需完整无修改)。

内容的提问来源于stack exchange,提问作者Boris K

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 20:55:22