当前位置:首页 » 《我的小黑屋》 » 正文

前端和Java验签以太坊钱包签名实现中心化登录

9 人参与  2024年05月01日 13:00  分类 : 《我的小黑屋》  评论

点击全文阅读


引言

相信做过一些dapp项目的小伙伴都知道,当dapp需要和中心化的业务系统交互时,怎么验证登录成了一个问题。要dapp输入登录账户密码就很奇怪,违背了设计初衷,不登录吧,中心化系统又没有安全可言。
故此需要一个特定的动作。只有当钱包持有人授权登录(连接钱包),前端js通过调用特定api加密得到算法,从而传到后台验证签名,从而达到登录效果。

前端js 加密代码(web.js)

// 这里一下没找到前端代码,从别人哪里拿过的-见谅import {ethers,providers} from 'ethers';class WalletHolder{    provider:providers.Provider;    signer:providers.JsonRpcSigner;    accounts:Array<string>;    constructor(_provider:providers.Provider,_signer:providers.JsonRpcSigner,_accounts:Array<string>) {        this.provider = _provider;        this.signer = _signer;        this.accounts = _accounts;    }}export default class WalletUtils{    public static async metamask() : Promise<Array<any>> {        try {            var provider = new ethers.providers.Web3Provider(window['ethereum']);            var accounts = await provider.send("eth_requestAccounts", []);            var signer = await provider.getSigner();            console.log("Account:", await signer.getAddress());        } catch (error) {          return [null,error]           }        return [new WalletHolder(provider,signer,accounts),null];    }    static holder:WalletHolder;        public static get signer() : providers.JsonRpcSigner {        return WalletUtils.holder.signer;    }    public static get provider() : providers.Provider {        return WalletUtils.holder.provider;    }            public static get accounts() : Array<string> {        return WalletUtils.holder.accounts;    }            public static async init(){        const[holder,error] = await WalletUtils.metamask();        if(error){            console.error('init metamask error',error)            return;        }        if(holder instanceof WalletHolder){            WalletUtils.holder = holder;            console.log('init success')        }    }}  if(!WalletUtils.holder){   await WalletUtils.init();  }  const defaultSinger  = WalletUtils.signer;       //使用签名及逆行   const message = await defaultSinger.signMessage("areyouok!")           //content = "hgqZgU7IuZM8y1rWUQOaMCbbb2QS39EtNWvLGu9FyDvTTQD/cOiLkgYNy+xGl/oEh/idTY2xNh9Kdpmg+ljgfFnd8R8bOEZ2JH38c4Jlhhm6ypntKdVKgrm9dquk8En4sZw1R/mEh8O7sSQ7kLOBv6Epzme0ZGyXJVWA4accjBo=";          // sing= "0xcb0a1688018b8cd8f0f5dd66647de8bb251772bc4aa64c9ac8ffc37af29299462f0ee7715646b8172e381bdf44ac5970180bbc10d31de1b6ec59a09d620fa8e21b";          //walletAddress = "0x37949e80Aedc7d72CFB3667d092161EA8729Ba49";

java验签

引入pom

  <!--web3j-->        <dependency>            <groupId>org.web3j</groupId>            <artifactId>core</artifactId>            <version>5.0.0</version>        </dependency>        <dependency>            <groupId>org.web3j</groupId>            <artifactId>geth</artifactId>            <version>5.0.0</version>            <exclusions>                <exclusion>                    <groupId>com.squareup.okhttp3</groupId>                    <artifactId>okhttp</artifactId>                </exclusion>            </exclusions>        </dependency>        <dependency>            <groupId>org.web3j</groupId>            <artifactId>abi</artifactId>            <version>5.0.0</version>        </dependency>

为了方便java同学测试,我这里附上 验签代码加密代码,线上只需要验签代码,因为加密代码由前端同学完成了。

import org.web3j.crypto.Credentials;import org.web3j.crypto.Keys;import org.web3j.crypto.Sign;import org.web3j.utils.Numeric;import java.math.BigInteger;import java.security.SignatureException;import java.util.Arrays;/** * @Description: Web3j签名验签 */public class ECRecoverUtil {     public static void main(String[] args) throws SignatureException {        String content = "hgqZgU7IuZM8y1rWUQOaMCbbb2QS39EtNWvLGu9FyDvTTQD/cOiLkgYNy+xGl/oEh/idTY2xNh9Kdpmg+ljgfFnd8R8bOEZ2JH38c4Jlhhm6ypntKdVKgrm9dquk8En4sZw1R/mEh8O7sSQ7kLOBv6Epzme0ZGyXJVWA4accjBo=";        String     sing= "0xcb0a1688018b8cd8f0f5dd66647de8bb251772bc4aa64c9ac8ffc37af29299462f0ee7715646b8172e381bdf44ac5970180bbc10d31de1b6ec59a09d620fa8e21b";        String walletAddress = "0x37949e80Aedc7d72CFB3667d092161EA8729Ba49";        boolean mark = validate(sing,content,walletAddress);        System.out.println(sing);        System.out.println(mark);    }    /**     * 签名     *     * @param content    原文信息     * @param privateKey 私钥     */    public static String signPrefixedMessage(String content, String privateKey) {        // todo 如果验签不成功,就不需要Hash.sha3 直接content.getBytes()就可以了        // 原文信息字节数组//        byte[] contentHashBytes = Hash.sha3(content.getBytes());        byte[] contentHashBytes = content.getBytes();        // 根据私钥获取凭证对象        Credentials credentials = Credentials.create(privateKey);        //        Sign.SignatureData signMessage = Sign.signPrefixedMessage(contentHashBytes, credentials.getEcKeyPair());        byte[] r = signMessage.getR();        byte[] s = signMessage.getS();        byte[] v = signMessage.getV();        byte[] signByte = Arrays.copyOf(r, v.length + r.length + s.length);        System.arraycopy(s, 0, signByte, r.length, s.length);        System.arraycopy(v, 0, signByte, r.length + s.length, v.length);        return Numeric.toHexString(signByte);    }    /**     * 验证签名     *     * @param signature     验签数据     * @param content       原文数据     * @param walletAddress 钱包地址     * @return 结果     */    public static Boolean validate(String signature, String content, String walletAddress) throws SignatureException {        if (content == null) {            return false;        }        // todo 如果验签不成功,就不需要Hash.sha3 直接content.getBytes()就可以了        // 原文字节数组//        byte[] msgHash = Hash.sha3(content.getBytes());        byte[] msgHash = content.getBytes();        // 签名数据        byte[] signatureBytes = Numeric.hexStringToByteArray(signature);        byte v = signatureBytes[64];        if (v < 27) {            v += 27;        }        //通过摘要和签名后的数据,还原公钥        Sign.SignatureData signatureData = new Sign.SignatureData(                v,                Arrays.copyOfRange(signatureBytes, 0, 32),                Arrays.copyOfRange(signatureBytes, 32, 64));        // 签名的前缀消息到密钥        BigInteger publicKey = Sign.signedPrefixedMessageToKey(msgHash, signatureData);        // 得到公钥(私钥对应的钱包地址)        String parseAddress = "0x" + Keys.getAddress(publicKey);        // 将钱包地址进行比对        return parseAddress.equalsIgnoreCase(walletAddress);    }}

点击全文阅读


本文链接:http://m.zhangshiyu.com/post/102623.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 《跟男友分手后,我成了他的白月光》程允川祝蓉蓉免费小说全文阅读_全本免费小说《跟男友分手后,我成了他的白月光》(程允川祝蓉蓉) -
  • 情散缘灭,你我绝然全章节(苏宸江雨柔)抖音热文_《情散缘灭,你我绝然全章节》最新章节免费在线阅读 -
  • 夜短梦未央全文阅读(夏琴韵顾越泽)最新热门小说_《夜短梦未央全文阅读》全集免费阅读 -
  • 孟晚森尹落月(等一个温晴暖冬热门小说)全文免费阅读无弹窗大结局_(孟晚森尹落月)等一个温晴暖冬热门小说免费阅读全文最新章节列表_笔趣阁(孟晚森尹落月) -
  • 寒夜孤灯对月明(裴行之沈卿璇)免费阅读 -
  • 你是我路过的四季全文阅读免费(傅清寒江宴婉)全文免费阅读无弹窗大结局_(你是我路过的四季全文阅读小说免费阅读)最新章节列表_笔趣阁(你是我路过的四季全文阅读) -
  • 雀登枝(邵麟锦明)小说完整版免费阅读_完结版免费小说雀登枝邵麟锦明 -
  • 《重生后,我踹掉夫君做女皇》沈洄崔青禾完结小说_完整版小说全文免费阅读《重生后,我踹掉夫君做女皇》沈洄崔青禾 -
  • 农门有喜:夫君别傲娇完整版小说,农门有喜:夫君别傲娇周景秀
  • 林知微时幸川小说在线免费阅读(错把真情付海棠无弹窗无删减)
  • 小说《一蓑烟雨春满城》免费阅读
  • 不原谅!虐师妹一时爽,全宗火葬场最新章节,不原谅!虐师妹一时爽,全宗火葬场免费阅读

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1