在Solidity合约中使用mapping存储密码是否安全?
结论:这种做法完全不安全,绝对不要在生产环境使用
- 首先搞清楚Solidity里
private修饰符的真实作用:它仅限制其他合约无法直接读取该变量,不代表数据会被加密隐藏。区块链的所有存储内容都是公开透明的,任何人都可以通过节点RPC接口直接查询合约的存储槽数据,你存在mapping里的明文密码任何人都可以轻松获取。哪怕你改存密码的哈希值,简单密码也可以通过彩虹表反向破解出原文,依然无法保证安全。 - 其次你写的验证逻辑本身有致命漏洞:调用
Authentication函数时传入的明文密码_passwd会作为交易数据全网广播,不管你存不存密码,只要把明文密码当参数传,这笔交易上链后所有人都能看到你输入的密码。
你给出的示例代码如下:
pragma solidity >=0.7.0 <0.9.0; contract Passwordtest{ //some code mapping (address => string) private passwd; function Authentication(string _passwd) { //compare the passwords and do something } }
链上身份验证的正确实现方式
不要用传统互联网的账号密码体系套在链上场景里,以太坊原生的非对称加密账户体系已经解决了身份验证问题,正确的做法是使用签名验证:
- 链下让用户用自己的钱包私钥对一段约定好的消息进行签名
- 用户调用合约时传入签名内容,合约通过
ecrecover接口恢复出签名对应的地址 - 对比恢复出的地址和调用者地址是否一致,就能完成身份验证,全程不需要在链上存储任何敏感信息,也不会泄露任何验证凭据。
内容的提问来源于stack exchange,提问作者Krzug
相关产品推荐
相关产品推荐

