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

这篇具有很好参考价值的文章主要介绍了前端和Java验签以太坊钱包签名实现中心化登录。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

相信做过一些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同学测试,我这里附上 验签代码加密代码,线上只需要验签代码,因为加密代码由前端同学完成了。文章来源地址https://www.toymoban.com/news/detail-855810.html


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);
    }

}

到了这里,关于前端和Java验签以太坊钱包签名实现中心化登录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java基于BC包的实现SM2签名验签方案,以及SM2签名中bc包冲突的部分解决方法

    信创改造也有一段时间了,这里记录和总结一些关于SM2算法的知识点。 或 由于BC包版本多种多样,且实现SM2算法的过程和结果并不相同。因此在引入bc包时,需要考虑bc包版本的问题,否则将出现包冲突或 ClassNotFound 的问题。 这里特别强调 ,特别是进行SDK开发时,需询问接入

    2024年02月14日
    浏览(40)
  • Java应用服务系统安全性,签名和验签浅析

    随着互联网的普及,分布式服务部署越来越流行,服务之间通信的安全性也是越来越值得关注。这里,笔者把应用与服务之间通信时,进行的的安全性相关, 加签 与 验签 ,进行了一个简单的记录。 网关服务接口,暴漏在公网,被非法调用? 增加了token安全验证,被抓包等

    2024年02月13日
    浏览(31)
  • 什么是“中心化”和“去中心化”?区块链是怎么实现去中心化的?

    图1 三类网络拓扑结构 所谓“中心化”和“去中心化”,最早是用来刻画网络拓扑结构的术语。1964年,美国兰德公司发布了一份关于分布式通信的报告,提出了三种网络结构(如图1)。其中,(a)类结构被称为“中心化星型网络”,(b)类结构被称为“去中心化网络”,(

    2024年02月11日
    浏览(39)
  • QT使用OpenSSL的接口实现RSA2的签名和验签

    加密和签名在RSA加密算法中是两个不同的概念,虽然它们都涉及RSA密钥对的使用,但目的和应用场景有所不同。 加密 (encrypt/decrypt) : 加密 :使用接收方的公钥对数据进行加密,只有拥有相应私钥的接收方才能解密数据。 解密 :使用接收方的私钥对加密数据进行解密,从而获

    2024年02月22日
    浏览(32)
  • c# .net framework 实现微信支付v3 h5支付 签名 验签

    接口文档:微信支付-开发者文档 (qq.com)    遇到的问题有   1、签名老验证不过去 :      生成的签名老验证不过    n 不要加转义符   2、 发送的请求老是400  使用工具请求正常。代码不行。   UserAgent = \\\"m.cnblogs.com/WebRequest\\\";    不要留空就行 网址可填自己的

    2024年02月05日
    浏览(35)
  • 关于去中心化技术实现的意义

    谈起去中心化,我们首先得知晓何谓中心化?所谓中心化就是一切以中央为转移。古代的皇权社会就是典型的中心化组织,天下以皇帝为权力中心,一切经济、文化、政治等天下大事都以皇帝为转移,才算合法合规,不然就是“忤逆王法”。“普天之下,莫非王土;率土之滨

    2024年02月14日
    浏览(27)
  • 空投:实现去中心化、建立DAO的必经之路

    当一个去中心化应用推出原生代币,那它首先得考虑如何给用户空投。 为什么要空投代币给用户? 因为它需要去中心化(至少官方是这样说的)。 空投可定义为“为用户分发代币的行为”。 1.空投的意义 起初的空投大多为了营销与扩大知名度。   Uniswap 对 18w 用户空投总价

    2023年04月14日
    浏览(32)
  • 区块链:实现无中心化互联网2.0的关键

    区块链技术是一种分布式、去中心化的数字账本技术,它允许多个节点共同维护一个完全透明且不可篡改的数字账本。这种技术首次在2008年的一篇论文中被提出,并在2009年的比特币项目中得到了实际应用。以来,区块链技术已经吸引了全球各行各业的关注,并被认为是实现

    2024年04月16日
    浏览(30)
  • DApp创建本地钱包并实现签名转账(BSC,Polygon,ETH)

    安装ether.js 引入ether.js:的三种方法 es3: es5/es6 javascript/typescript es6 这里默认为你已经了解 地址、密码、私钥、助记词、Keystore 之间的关系,所以不再过多介绍,只列出他们之间的关联: 使用到的ethers的Wallet类: createRandom 返回一个带有随机私钥的新钱包,由加密安全的熵源生成。如

    2024年02月09日
    浏览(31)
  • 基于ERC20代币协议实现的去中心化应用平台

    使用 solidity 实现的基于 ERC20 代币协议的借贷款去中心化应用平台(极简版)。实现存款、取款、贷款、还款以及利息计算的功能。 平台提供ERC20协议代币的相关存取和利息计算工作。部署智能合约时初始化贷款和存款的年利率、代币实现地址。 用户可以将手中的代币存入平台

    2024年02月04日
    浏览(60)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包