Go椭圆曲线数字签名、验证_注意做一个针对任意输入的椭圆曲线签名,需要输出哈希的结果,签名的结果,并且验证-程序员宅基地

技术标签: 算法  区块链  Go自带椭圆曲线  go  

椭圆曲线数字签名及验证

1.生成私钥和公钥
  • 生成椭圆曲线对象
  • 生成密钥对,返回私钥对象
  • 编码生成公钥字节数组,参数是椭圆曲线、x坐标、y坐标
2.ECDSA数字签名
  • 数字签名生成r、s的big.Int对象,参数是随机数、私钥、签名文件的哈希串
  • 将r、s转成r、s字符串
  • r和s字符串凭借,形成数字签名的der格式
3.生成签名的DER编码格式
  • 获取r和s的长度
  • 计算DER序列的总长度
  • 将10进制长度转16进制字符串
  • 平凑DER编码格式
4.ECDSA验证签名
  • 生成椭圆曲线对象
  • 根据公钥字节数字,获取公钥中的x及y
  • 生成公钥对象
  • 对der格式的签名进行解析,获取r、s字节数组后转成big.Int类型
  • 验证签名。参数是共要对象、签名文件的哈希串、数字签名的r和s对象
Go代码实现
package main

import (
	"crypto/ecdsa"
	"crypto/elliptic"
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"log"
	"math/big"
)

func main()  {
    
	//1.对需要签名的文件进行hash运算
	data := "Oneck"
	hashInstance := sha256.New()
	hashInstance.Write([]byte(data))
	hashed := hashInstance.Sum(nil)

	//2.生成公钥私钥
	privateKey, publicKeyBytes := NewKeyPair()

	//3.生成签名的DER格式
	derSignString := ECDSASign(hashed,privateKey)
	fmt.Sprintf("签名信息为:\n",derSignString)

	//4.验证签名
	flag := ECDSAVerfy(publicKeyBytes,hashed,derSignString)
	fmt.Println("签名验证结果",flag)
}

func NewKeyPair() (ecdsa.PrivateKey,[]byte) {
    
	//- 生成椭圆曲线对象
	curve := elliptic.P256()
	//- 生成密钥对,返回私钥对象
	privateKey, err := ecdsa.GenerateKey(curve,rand.Reader)
	if err != nil {
    
		log.Panic(err)
	}
	//- 编码生成公钥字节数组,参数是椭圆曲线、x坐标、y坐标
	publicKeyBytes := elliptic.Marshal(curve,privateKey.X,privateKey.Y)
	fmt.Printf("公钥 %x\n",publicKeyBytes)
	return  *privateKey,publicKeyBytes
}

//ECDSA数字签名
func ECDSASign(hashed []byte,privateKey ecdsa.PrivateKey) string {
    
	//- 数字签名生成r、s的big.Int对象,参数是随机数、私钥、签名文件的哈希串
	r,s,err := ecdsa.Sign(rand.Reader,&privateKey,hashed)
	if err != nil {
    
		return ""
	}
	//- 将r、s转成r、s字符串
	strSigR := fmt.Sprintf("%x",r)
	strSigS := fmt.Sprintf("%x",s)
	if len(strSigR) == 63 {
    
		strSigR = "0" + strSigR
	}
	if len(strSigS) == 63 {
    
		strSigR = "0" + strSigS
	}
	fmt.Printf("r的16进制为:%s,长度为%d\n",strSigR,len(strSigR))
	fmt.Printf("s的16进制为:%s,长度为%d\n",strSigS,len(strSigS))
	//- r和s字符串凭借,形成数字签名的der格式
	derString := MakeDerSign(strSigR,strSigS)
	return derString
}

//生成数字签名的DER编码格式
func MakeDerSign(strR,strS string) string {
    
	//获取R和S的长度
	lenSigR := len(strR)/2 //16进制每两位1字节
	lenSigS := len(strS)/2
	//- 计算DER序列的总长度
	len := lenSigR + lenSigS + 4
	//- 将10进制长度转16进制字符串
	strLenSigR := fmt.Sprintf("%x",int64(lenSigR))
	strLenSigS := fmt.Sprintf("%x",int64(lenSigS))
	strLen := fmt.Sprintf("%x",int64(len))
	//- 拼凑DER编码格式
	derString := "30" + strLen
	derString += "02" + strLenSigR + strR
	derString += "02" + strLenSigS + strS
	derString += "01"
	return  derString
}

//ECDSA验证签名
func ECDSAVerfy(publicKeyBytes,hashed []byte,derSignString string) bool {
    
	//公钥长度
	keyLen := len(publicKeyBytes)
	if keyLen != 65 {
    
		return false
	}
	//- 生成椭圆曲线对象
	curve := elliptic.P256()
	//- 根据公钥字节数字,获取公钥中的x及y
	publicKeyBytes = publicKeyBytes[1:]
	x := new(big.Int).SetBytes(publicKeyBytes[:32])
	y := new(big.Int).SetBytes(publicKeyBytes[32:])
	//- 生成公钥对象
	publicKey := ecdsa.PublicKey{
    curve,x,y}
	//- 对der格式的签名进行解析,获取r、s字节数组后转成big.Int类型
	rBytes,sBytes := ParseDERSignString(derSignString)
	r := new(big.Int).SetBytes(rBytes)
	s := new(big.Int).SetBytes(sBytes)
	//- 验证签名。参数是共要对象、签名文件的哈希串、数字签名的r和s对象
	return ecdsa.Verify(&publicKey,hashed,r,s)
}

//如传入是r/s调用此函数
func ECDSAVerfy1(publicKeyBytes,hashed,rBytes,sBytes []byte) bool {
    
	//公钥长度
	keyLen := len(publicKeyBytes)
	if keyLen != 65 {
    
		return false
	}
	//- 生成椭圆曲线对象
	curve := elliptic.P256()
	//- 根据公钥字节数字,获取公钥中的x及y
	publicKeyBytes = publicKeyBytes[1:]
	x := new(big.Int).SetBytes(publicKeyBytes[:32])
	y := new(big.Int).SetBytes(publicKeyBytes[32:])
	//- 生成公钥对象
	publicKey := ecdsa.PublicKey{
    curve,x,y}
	r := new(big.Int).SetBytes(rBytes)
	s := new(big.Int).SetBytes(sBytes)
	//- 验证签名。参数是共要对象、签名文件的哈希串、数字签名的r和s对象
	return ecdsa.Verify(&publicKey,hashed,r,s)
}
func ParseDERSignString(derString string) (rBytes,sBytes []byte) {
    
	derBytes,_ := hex.DecodeString(derString)
	rBytes = derBytes[4:36]
	sBytes = derBytes[len(derBytes) - 33 : len(derBytes) - 1]
	return

}

在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_45828877/article/details/104026154

智能推荐

pki的java实现书籍_精通PKI网络安全认证技术与编程实现 PDF扫描版[214MB]-程序员宅基地

文章浏览阅读240次。精通PKI网络安全认证技术与编程实现从实战出发,介绍了PKI应用开发过程和细节。《精通PKI网络安全认证技术与编程实现》共32章,分6篇,主要内容包括PKI基础知识、OpenSSL开发、CrytoAPI开发、JavaSecurity开发、电子商务网站应用、PKI技术应用等,涉及C语言、Java语言、JSP、ASP/ASP.NET、PHP等开发语言。为了方便读者深入了解PKI,《精通PKI网络安全认..._api安全技术与实战pdf

c语言字符串函数 小数,C语言modf()函数:求双精度数的小数部分-程序员宅基地

文章浏览阅读644次。函数名: modf头文件:函数原型: double modf(double value, double *iptr);功 能: 求双精度数的小数部分参 数: double value 为要操作的双精度数 ,double *iptr 为要传回整数部分的变量指针返回值: 返回value的小数部分程序例: 分别求出双精度number的小数部分和整数部分,并将结果输出#include#includ..._c语言求一个双精度数的整数部分和小数部分

SYN flood_http存在synflood吗-程序员宅基地

文章浏览阅读288次。最近在学习DDos相关知识,参考一些只是,做了摘要,供自己参考。 参考:http://blog.csdn.net/xlf13872135090/article/details/8059538SYN Flood 攻击原理 利用TCP协议缺陷,发送了大量伪造的TCP连接请求,使得被攻击方资源耗尽,无法及时回应或处理正常的服务请求。一个正常的TCP连接需要三次握手,首先客户端发送一个包含SYN标志的数_http存在synflood吗

测牛学堂:软件测试之数据库操作语句sql的外键查询_sql查询外键id的数据-程序员宅基地

文章浏览阅读775次。我们之前学习的都是针对一个表的操作。如果要进行多个表之间的操作,就要用到外键把他们关联起来。外键的作用:能够让多个表进行关联,使表与表之间有联系,实现共性抽取。如果数据项比较多的情况下,把所有数据都存放在一个表中,如果表太大,影响操作效率。解决办法就是把一个表拆分成多个表,并且用外键去关联。例子:如果要设计一个员工表1)员工表:编号、姓名、年龄、性别、所在分公司、所在部门2)部门表:编号、部门名称、部门经理、主要任务3)公司表:编号、分公司名,地址、电话、法人把公司和部门的数据抽取出来,形成_sql查询外键id的数据

OpenGL学习笔记【4】——创建窗口,给窗口添加渲染颜色_opengl窗口颜色-程序员宅基地

文章浏览阅读803次,点赞14次,收藏14次。章节一讲述了OpenGL在渲染的时候需要一个Context来记录了OpenGL渲染需要的所有信息和状态,可以把上下文理解成一个大的结构体,它里面记录了当前绘制使用的颜色、是否有光照计算以及开启的光源等。不同的操作系统,都有各自的上下文创建方法,最简单的上下文可以通过创建。章节二讲述了一个一个轻量级的图形界面框架,GLFW 的是提供了处理手柄、键盘、鼠标输入章节二还创建了一个空项目章节三讲述了GLAD库是用来管理OpenGL的函数指针的,所以在调用任何OpenGL的函数之前我们需要,从而让我们。_opengl窗口颜色

java ssm 运行步骤_SSM三大框架的运行流程、原理、核心技术详解-程序员宅基地

文章浏览阅读644次。一、Spring部分1、Spring的运行流程·第一步:加载配置文件ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");,ApplicationContext接口,它由BeanFactory接口派生而来,因而提供了BeanFactory所有的功能。配置文件中的bean的信息是被加载在HashMap中的,一个..._ssm那个文件是运行

随便推点

linux 找不到防火墙设置的,linux怎么样查看防火墙有没开启-程序员宅基地

文章浏览阅读2.6k次。我的是linux系统,那么要怎么样才能查看防火墙有没有开启呢?下面由学习啦小编给你做出详细的linux查看防火墙是否开启方法介绍!希望对你有帮助!linux查看防火墙是否开启方法一:service iptables status可以查看到iptables服务的当前状态。但是即使服务运行了,防火墙也不一定起作用,你还得看防火墙规则的设置 iptables -L在此说一下关于启动和关闭防火墙的命令:1..._linux防火墙服务找不到

C# DatrgridView表格控件的一些用法-程序员宅基地

文章浏览阅读109次。public class useDatrgrivView { string conn = null; string sqlComm = null; DataSet das = null; DataGridView GridView = null; //初始化,绑定 publ..._datrgridview 显示不了数据

rem和vw的分析比较_rem和vw兼容性-程序员宅基地

文章浏览阅读6.5k次,点赞3次,收藏9次。rem:首先rem是css单位,相比于px固定的像素单位,rem是相对像素单位,更加的灵活。需求存在:现在移动端各种屏幕的出现,适应性就更加的强烈。根据分辨率的不同让html的字体大小变化。一、基本原理:我们在页面中写rem,由于rem是相对于根元素字体大小来计算的,那么就可以实现自适应的效果。Rem原理举例:设计稿宽度:x px移动设备宽度:y pxHtml中font-size..._rem和vw兼容性

【Ubuntu】Ubuntu 20.04安装Python3.7_ubuntu server 20.04 完整安装python3.7-程序员宅基地

文章浏览阅读1.6w次,点赞5次,收藏81次。注意:转入root权限下1. 升级# sudo apt update# sudo apt upgrade -y2. 安装编译Python源程序所需的包# sudo apt install build-essential -y# sudo apt install libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev -y# sudo apt-get install zlib1g-dev._ubuntu server 20.04 完整安装python3.7

matlab建模DNA双链,PPT绘制科研图形—DNA双链、分子细胞模型-程序员宅基地

文章浏览阅读1.3k次。原标题:PPT绘制科研图形—DNA双链、分子细胞模型 PPT绘制DNA双链 1用矩形工具画一个矩形如下,线条颜色设置为无,填充色如下图蓝色 2选中矩形框,选择菜单栏的“格式—— 编辑形状——转换为任意多边形” 3这个时候再看下“编辑形状”,可以看到“编辑顶点” 已经为可用状态 4点击“编辑顶点“,矩形框四个角变为黑色实点。可以拖动实点变为如下图示。然后在边缘上右键,选择”添加顶点“,添加如下顶点 ..._matlab双螺旋结构模型图怎么画

duilib vs2015 安装_DuiLib(1)——简单的win32窗口-程序员宅基地

文章浏览阅读169次。资源下载https://yunpan.cn/cqF6icWRN5CTc 访问密码 92e3 注:DUILIB库.7z 是vs2015下编译好的动态库及静态库,如上图所示一、新建一个win32工程项目设置中选择:debug,常规中:全程无优化-全程无优化,多线程调试 (/MTd);我的项目选择的是静态编译,使用的是静态库,就不需要带duilib.dll文件了代码如下:#include #inclu..._vs2015使用duilib

推荐文章

热门文章

相关标签