Go学习第八天

签名

java 复制代码
func (a *Account) Sign(message []byte) ([]byte, error) {
	hash := crypto.Keccak256Hash(message)
	signature, err := crypto.Sign(hash.Bytes(), a.privateKeyECDSA)
	if err != nil {
		log.Fatal(err)
	}
	signMsg := []byte(hexutil.Encode(signature))
	return signMsg, err
}

验签

java 复制代码
func (a *Account) VerifySign(signatureHex, message string) (bool, error) {
	// 签名 Hex 转 Bytes
	signature, err := hexutil.Decode(signatureHex)
	if err != nil {
		return false, errors.New("签名后的数据解析异常")
	}
	// msg 转 hash
	newHash := crypto.Keccak256Hash([]byte(message))

	// 由于前端工具差异, 可能需要重新 Hash
	//var newHash []byte
	if signature[64] > 30 {
		signature[64] -= 31
		//newHash = signHash(hash.Bytes())
	} else {
		signature[64] -= 27
		//newHash = hash.Bytes()
	}

	sigPublicKeyECDSA, err := crypto.SigToPub(newHash.Bytes(), signature)
	if err != nil {
		return false, errors.New("签名解出公钥椭圆曲线异常")
	}

	// 一个重要的问题是我们必须首先删除signture的最后一个字节,因为它是ECDSA恢复ID,不能包含它。
	sigPublicKeyBytes := crypto.FromECDSAPub(sigPublicKeyECDSA)
	signatureNoRecoverID := signature[:len(signature)-1]

	recoveredAddr := crypto.PubkeyToAddress(*sigPublicKeyECDSA)
	if string(a.PublicKey()) != recoveredAddr.Hex() {
		return false, errors.New("签名解出公钥异常")
	}

	// 该函数接收原始数据的签名,哈希值和字节格式的公钥。 它返回一个布尔值,如果公钥与签名的签名者匹配,则为true。
	verified := crypto.VerifySignature(sigPublicKeyBytes, newHash.Bytes(), signatureNoRecoverID)
	if !verified {
		return false, errors.New("验签失败")
	}
	return verified, nil
}
相关推荐
曾浩轩12 分钟前
图灵完备Turing Complete 3
学习
天天睡大觉20 分钟前
Python学习11
网络·python·学习
laplace012328 分钟前
# 第六章 agent框架开发实践 - 学习笔记
人工智能·笔记·学习·语言模型·agent
AI即插即用43 分钟前
即插即用系列(代码实践)专栏介绍
开发语言·人工智能·深度学习·计算机视觉
码农水水1 小时前
蚂蚁Java面试被问:混沌工程在分布式系统中的应用
java·linux·开发语言·面试·职场和发展·php
喵了meme1 小时前
c语言经验分享
c语言·开发语言
Knight_AL1 小时前
用 JOL 验证 synchronized 的锁升级过程(偏向锁 → 轻量级锁 → 重量级锁)
开发语言·jvm·c#
坚持不懈的大白1 小时前
Leetcode学习笔记
笔记·学习·leetcode
啊阿狸不会拉杆2 小时前
《数字图像处理》第 4 章 - 频域滤波
开发语言·python·数字信号处理·数字图像处理·频率域滤波
SWAGGY..2 小时前
数据结构学习篇(10)--- 二叉树基础oj练习
数据结构·学习