以太坊二层账户密钥可以兼容智能合约、隔离账户风险,并且对 SNARK 友好,了解一下它的生成方法。

原文标题:《以太坊二层账户密钥生成指南》
撰文:因雨成歌

最近,Loopring Exchange 发生了一起因前端漏洞引发的安全事件,导致中继服务紧急停止。所有用户在交易前需要更新其 EdDSA 密钥对。有关该错误的完整说明请参见 Starkware 的博客 [1]。

幸运的是,事件并未造成损失。然而,关于弱私钥的漏洞屡屡发生,由于使用不当而造成大量损失。据 WEIRD[2],由于使用「脑钱包」(一种不正确的方法来生成私钥),超过 2800 个比特币和 40,000 个以太币被盗。但在 Loopring 事件中情况略有不同。出现风险的是用于 ZK Rollup 的新密钥,而不是以太坊账户的密钥,或者如 Starkware 所说,这是一个账户密钥。以太坊密钥仍然处于安全状态。为什么需要账户密钥而不是使用以太坊密钥?如何安全地生成和保存它?

为什么我们需要一个账户密钥?

ZK Rollup 增强了以太坊的可扩展性,同时安全性仍保持在 L1 级别。与新手用户不同,ZK Rollup 的用户很可能已经拥有一个以太坊账户。为什么仍需要一个账户密钥?主要有三个原因。

SNARK 友好

账户密钥需要对 SNARK 友好。与以太坊密钥不同,它使用不同的椭圆曲线(例如 Ed25519,取代 secp256k1)。通常,EdDSA 密钥用于签署链下请求,因为它对 SNARK 更为友好。但是,因为私钥的长度相同,仍然可以使用与以太坊密钥相同的私钥,但显然对应的公钥是不同的。

兼容智能合约账户

由于中继器需要签名来检查链下交易的有效性并生成证明,因此它不适用于合同账户。最佳实践是使用以太坊账户授权创建一个新的密钥对,这样对外部账户和合约账户都适用。

风险隔离

链下签名带来了新的安全风险。如果以太坊密钥用于 ZK Rollup,则账户密钥的泄漏意味着以太坊帐户不再安全。使用不同的账户密钥可以隔离风险,即使账户密钥被盗或丢失,以太坊密钥也可以保持安全。

如何生成账户密钥?

私钥必须完全随机且不可预测,并且密钥空间应足够大。因此,问题似乎等同于生成随机数。这看似可行,但并非那么容易,因为这需要收集足够的噪声。但是,如果以太坊账户已经存在,我们可以使用多种方法来确定性地从以太坊账户生成一个账户密钥。

使用以太坊账户签名

简单来说,我们可以通过指定签名从私钥生成账户密钥。如 Vitalik[3] 所述,account_key = ecdsa_sign (private_key,「 42」)。可使用有意义的消息代替「 42」,以警告用户他在做什么,例如「签署此消息以登录 xxx。」。如果以太坊账户是合约账户,则将使用 EIP-1271 来检查有效性。

对签名进行哈希

Matter Labs 的联合创始人 Alex Gluchowski 改进了 Vitalik 的建议 [4],account_key = sha256(ecdsa_sign(private_key, 「Sign this message to login to service xyz」))。他强调说:「从密码分析的角度来看,sha256 (或另一个伪随机哈希)很重要:签名是椭圆曲线的点,因此我们需要打破两个密钥之间的任何潜在关系。」实际上,这种方法已在 zkSync 中使用。

这看起来类似简化版的 PBKDF2[5] 协议。但是,我希望对此有更正式的安全分析或证明,因为近来的一些研究成果指出基于哈希的 MAC 存在安全风险。

Loopring 的新方法

在最新的文章 [6] 中,Loopring 提出了一种生成账户密钥的新方法。Loopring 采纳了 Alex 和 Vitalik 的建议。此外,引入了计数器 n,这样用户更新账户密钥时,可以确定性地产生不同的私钥。

总而言之,我们可以借助数字签名、伪随机预言机和计数器等技术手段,从以太坊账户中获得一个账户密钥。账户密钥是唯一且确定的。不过,你仍然可以选择生成一个随机数作为私钥。

如何管理账户密钥?

如果使用确定性的方式生成账户密钥,则不需要额外的手段来管理账户密钥。当我们需要为 Rollup 交易签名时,只需即时从以太坊账户中计算出账户密钥。以太坊密钥仍由数字货币钱包管理,这不会引入密钥管理中的额外安全风险。

尽管如此,大部分的账户密钥仍存储在浏览器中(极度不建议这样使用),加密钱包(包括硬件钱包)需要支持更多的加密原语,这样 DApp 才无需担心密钥管理的问题。

结论

我们可以确定性的方式从以太坊账户中生成一个账户密钥。账户密钥的安全级别可以与以太坊密钥相同。加密钱包需要支持更多的加密原语,以提供更好的安全基础架构。

参考资料:

[1]https://medium.com/starkware/looprings-frontend-vulnerability-explained-106df1aa17db

[2]https://www.wired.com/story/blockchain-bandit-ethereum-weak-private-keys/

[3]https://twitter.com/VitalikButerin/status/1258382081417187331

[4]https://twitter.com/gluk64/status/1258426478334787585

[5]https://eprint.iacr.org/2014/406.pdf

[6]https://blogs.loopring.org/new-approach-to-generating-layer-2-account-keys-cn/