以太坊二层账户密钥生成指南

最近,Loopring Exchange发生了一起因前端漏洞引发的安全事件,导致中继服务紧急停止。所有用户在交易前需要更新其EdDSA密钥对。有关该错误的完整说明请参见Starkware的博客[1]。
幸运的是,事件并未造成损失。然而,关于弱私钥的漏洞屡屡发生,由于使用不当而造成大量损失。据WEIRD[2],由于使用“脑钱包”(一种不正确的方法来生成私钥),超过2800个比特币和40,000个以太币被盗。但在Loopring事件中情况略有不同。出现风险的是用于zkRollup的新密钥,而不是以太坊账户的密钥,或者如Starkware所说,这是一个账户密钥。以太坊密钥仍然处于安全状态。为什么需要账户密钥而不是使用以太坊密钥?如何安全地生成和保存它?
为什么我们需要一个账户密钥?
zkRollup增强了以太坊的可扩展性,同时安全性仍保持在L1级别。与新手用户不同,zkRollup的用户很可能已经拥有一个以太坊账户。为什么仍需要一个账户密钥?主要有三个原因。
1.SNARK友好
账户密钥需要对SNARK友好。与以太坊密钥不同,它使用不同的椭圆曲线(例如Ed25519,取代secp256k1)。通常,EdDSA密钥用于签署链下请求,因为它对SNARK更为友好。但是,因为私钥的长度相同,仍然可以使用与以太坊密钥相同的私钥,但显然对应的公钥是不同的。
2.兼容智能合约账户
由于中继器需要签名来检查链下交易的有效性并生成证明,因此它不适用于合同账户。最佳实践是使用以太坊账户授权创建一个新的密钥对,这样对外部账户和合约账户都适用。
3.风险隔离
链下签名带来了新的安全风险。如果以太坊密钥用于zkRollup,则账户密钥的泄漏意味着以太坊帐户不再安全。使用不同的账户密钥可以隔离风险,即使账户密钥被盗或丢失,以太坊密钥也可以保持安全。
如何生成账户密钥?
私钥必须完全随机且不可预测,并且密钥空间应足够大。因此,问题似乎等同于生成随机数。这看似可行,但并非那么容易,因为这需要收集足够的噪声。但是,如果以太坊账户已经存在,我们可以使用多种方法来确定性地从以太坊账户生成一个账户密钥。
1.使用以太坊账户签名
简单来说,我们可以通过指定签名从私钥生成账户密钥。如Vitalik[3]所述,account_key = ecdsa_sign(private_key,“ 42”)。可使用有意义的消息代替“ 42”,以警告用户他在做什么,例如“签署此消息以登录xxx。”。如果以太坊账户是合约账户,则将使用EIP-1271来检查有效性。
2.对签名进行哈希
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存在安全风险。
3.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/