自学内容网 自学内容网

Go 实现:椭圆曲线数字签名算法ECDSA

一、ECDSA概述

     椭圆曲线数字签名算法(ECDSA)是使用椭圆曲线密码(ECC)对数字签名算法(DSA)的模拟。它基于椭圆曲线离散对数问题(ECDLP)的难解性,具有密钥短、速度快和安全性高的优点。与传统的离散对数问题(DLP)和大数分解问题(IFP)不同,椭圆曲线离散对数问题没有亚指数时间的解决方法,因此椭圆曲线密码的安全性更高。

二、ECDSA工作原理

ECDSA的签名过程包括以下步骤:

  1. 选择一条椭圆曲线Ep(a,b)和基点G;
  2. 选择私有密钥k(k<n,n为G的阶),利用基点G计算公开密钥K=kG;
  3. 产生一个随机整数r(r<n),计算点R=rG;
  4. 将原数据和点R的坐标值x,y作为参数,计算SHA1做为hash,即Hash=SHA1(原数据,x,y);
  5. 计算s≡r−Hash∗k(modn);
  6. r和s做为签名值,如果r和s其中一个为0,重新从第3步开始执行。

验证过程如下:

  1. 接受方在收到消息m和签名值r,s后,进行以下运算;
  2. 计算sG+H(m)P=(x1,y1),r1≡x1modp;
  3. 验证等式:r1≡rmodp;
  4. 如果等式成立,接受签名,否则签名无效。

三、Go实现

1. 生成私钥和公钥,生成的私钥为结构体ecdsa.PrivateKey的指针

func NewKeyPair()(ecdsa.PrivateKey,[]byte){
//生成secp256椭圆曲线
curve := elliptic.P256()
//产生的是一个结构体指针,结构体类型为ecdsa.PrivateKey
private,err := ecdsa.GenerateKey(curve, rand.Reader)
if err != nil{
log.Panic(err)
}


fmt.Printf("私钥:%x\n", private)
fmt.Printf("私钥X:%x\n", private.X.Bytes())
fmt.Printf("私钥Y:%x\n", private.Y.Bytes())
fmt.Printf("私钥D:%x\n", private.D.Bytes())

//x坐标与y坐标拼接在一起生成公钥
pubKey := append(private.X.Bytes(),private.Y.Bytes()...)
//打印公钥,公钥用16进制打印出来长度为128,包含了x轴坐标与y轴坐标。
fmt.Printf("公钥:%x \n", pubKey)

return *private, pubKey
}

2.生成签名的DER格式

func MakeSignatureDerString(r,s string)string{
//获取R和S的长度
lenSigR := len(r)/2
lenSigS := len(s)/2

//计算DER序列的总长度
lenSequence := lenSigR + lenS

原文地址:https://blog.csdn.net/Shinobi_Jack/article/details/142596487

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!