写点什么

web3 的身份验证之以太坊签名消息

作者:devpoint
  • 2022 年 6 月 29 日
  • 本文字数:1175 字

    阅读完需:约 4 分钟

web3 的身份验证之以太坊签名消息

如果参与过以太坊 DApp 相关的开发,可能遇到过要求签名一条消息或一条数据以验证自己(以及钱包地址)。本文将讨论以太坊签名数据的基础知识。

工作原理

在最高级别,签名消息是一种验证以太坊区块链上拥有特定钱包地址的方法。签名消息有 5 个基本要素:


  • 一个用户钱包地址(也称为账户地址)

  • 私钥(这些只有钱包所有者知道或可以生成,通常在用户界面和密码后面,如 MetaMask 的钱包一样)

  • 公钥(可以从帐户派生,但仅在签名消息或交易时)

  • 签名消息内容

  • 数学计算


所以现在来看看这些元素是如何协同工作的,假如有一个 DApp 或 web3 网站,并且想要验证用户是否拥有某个地址,此时只知道用户的帐户。所以提供一条消息,用户对其进行签名 signature (通常通过点击钱包中的按钮),在幕后签名 signature 使用消息、私钥和公钥以及一些数学计算。


要验证签名,可以使用一些数学运算以及消息,并且应该知道公钥,而公钥一般是钱包地址,如何确保安全,答案是加密/数学原酸,如果没有私钥,将无法从消息中获得与公钥相等的验证,从而证明所有权。当然这一切都不需要自己去实现,有相应的脚本库来支持,如web3.js。通俗来说就是通过 MetaMask 对一条消息进行签名获得一个签名串,在后台对签名串进行解密获得一个地址,这个地址如果与用户的钱包地址一致,就说明其拥有这个地址所有权。


虽然可以通过解锁钱包来登录 DApp,但在以太坊中签名消息是一种肯定的同意行为,考虑任何需要用户许可但不需要直接与以太坊的 EVM 交互或与 ETH 进行交易的事情,因此没有 gas 费用(至少对于简单的消息),当然它可以作为更严格的验证,即使用钱包登录的人实际上拥有钱包/地址。

如何实现

通常用于实现的方式有签名一条固定的消息或者随机字符串等等,如果是随机字符串,前端通过接口获取随机字符串,然后对其随机字符串进行签名,将签名后的字符串和地址作为参数提交给后台去进行验证。下面是一般的 UI 效果:



下面是通过 web3 实现的方法:


ethereum    .request({        method: "personal_sign",        params: [message, address],    })    .then((signature) => {        // 这里将签名串 signature 和地址通过接口发送到后台服务验证    })    .catch((err) => {        // 异常    });
复制代码


通常签名后的字符串如下:



对于后端的验证,验证使用的依赖库是 ethers ,代码如下:


/** * 验证签名及地址 * @param {*} message 签名消息 * @param {*} signerAddress 签名地址即用户钱包地址 * @param {*} signature 签名后的字符串 * @returns */const verifyMessage = async (message, signerAddress, signature) => {    const recoveredAddress = ethers.utils.verifyMessage(message, signature);
return recoveredAddress === signerAddress;};
复制代码

总结

对于 DApp 或者 Web3 的开发,设计的用户验证通常的机制就是通过签名消息来实现。


发布于: 刚刚阅读数: 5
用户头像

devpoint

关注

细节的追求者 2011.11.12 加入

专注前端开发,用技术创造价值!

评论

发布
暂无评论
web3 的身份验证之以太坊签名消息_区块链_devpoint_InfoQ写作社区