如何使用Java 验证以太坊钱包签名?

如何使用Java 验证以太坊钱包签名?,第1张

如何使用Java 验证以太坊钱包签名? 场景

在dapp应用中需要用户进行签名某个文本,后台验证这个文本来源于这个账号,然后进行对应的登录 *** 作,返回于服务器交互的token。

代码

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!")
            console.log(message)
            //0x8143e2b0a387f1e05b5f37c5ffdc88e29962a042d114f3f06df2679f6ce90a310d8d9df46fb595c6ab26fcbcbec9a6407c586956cfd5076f12ce8041024abcfd1c

后台验签方法

static boolean isSignatureValid(final String address, final String signature, final String message) {
        log.info("isSignatureValid invoked for Address {} with Signature {} and Message {} ", address, signature,
                message);

        final String personalMessagePrefix = "\u0019Ethereum Signed Message:\n";
        boolean match = false;

        final String prefix = personalMessagePrefix + message.length();
        final byte[] msgHash = Hash.sha3((prefix + message).getBytes());
        final byte[] signatureBytes = Numeric.hexStringToByteArray(signature);
        byte v = signatureBytes[64];
        if (v < 27) {
            v += 27;
        }

        final Sign.SignatureData sd = new Sign.SignatureData(v,
                Arrays.copyOfRange(signatureBytes, 0, 32),
                Arrays.copyOfRange(signatureBytes, 32, 64));

        String addressRecovered = null;

        // Iterate for each possible key to recover
        for (int i = 0; i < 4; i++) {
            final BigInteger publicKey = Sign.recoverFromSignature((byte) i, new ECDSASignature(
                    new BigInteger(1, sd.getR()),
                    new BigInteger(1, sd.getS())), msgHash);

            if (publicKey != null) {
                addressRecovered = "0x" + Keys.getAddress(publicKey);

                if (addressRecovered.equals(address)) {
                    match = true;
                    break;
                }
            }
        }

        return match;
    }

Java代码来源于 stackexchange 依赖用到了 web3j 4.8.4

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/743412.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-29
下一篇 2022-04-29

发表评论

登录后才能评论

评论列表(0条)

保存