Go-ecc数字签名详解与代码

简介: Go-ecc数字签名详解与代码

Go-数字签名详解与Rsa数字签名代码中已经讲了数字签名的原理,就不重复了

Ecc签名的Go实现

crypto/ecdsa包

func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error)

使用私钥对任意长度的hash值(必须是较大信息的hash结果)进行签名,返回签名结果(一对大整数)。私钥的安全性取决于密码读取器的熵度(随机程度)。

func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool

使用公钥验证hash值和两个大整数r、s构成的签名,并返回签名是否合法。

签名

  • 使用sha256.Sum356获取摘要
  • 使用ecdsa.Sign进行签名
  • 对r s进行序列化

// Ecc 签名

// plainText 明文

// priPath 私钥路径

// 返回 签名结果

func ECCSign(plainText []byte,priPath string) ([]byte,[]byte,error) {
  // get pem.Block
  block,err := util.GetKey(priPath)
  if err != nil{
    _, file, line, _ := runtime.Caller(0)
    return nil,nil,util.Error(file,line+1,err.Error())
  }
  // x509
  priKey,err := x509.ParseECPrivateKey(block.Bytes)
  if err != nil{
    _, file, line, _ := runtime.Caller(0)
    return nil,nil,util.Error(file,line+1,err.Error())
  }
  hashText := sha256.Sum256(plainText)
  // sign
  r,s,err := ecdsa.Sign(rand.Reader,priKey,hashText[:])
  if err != nil{
    _, file, line, _ := runtime.Caller(0)
    return nil,nil,util.Error(file,line+1,err.Error())
  }
  // marshal
  rText,err := r.MarshalText()
  if err != nil{
    _, file, line, _ := runtime.Caller(0)
    return nil,nil,util.Error(file,line+1,err.Error())
  }
  sText,err := s.MarshalText()
  if err != nil{
    _, file, line, _ := runtime.Caller(0)
    return nil,nil,util.Error(file,line+1,err.Error())
  }
  return rText,sText,nil
}

验证签名

  • 使用sha256.Sum356获取摘要
  • 对r s进行反序列化
  • 使用ecdsa.Verify进行签名认证

// ECC 签名验证

// plainText 明文

// rText,sText 签名

// pubPath公钥文件路径

// 返回 验签结果 错误

func ECCVerify(plainText,rText,sText []byte,pubPath string) (bool,error) {
  // get pem.Block
  block,err := util.GetKey(pubPath)
  if err != nil{
    _, file, line, _ := runtime.Caller(0)
    return false,util.Error(file,line+1,err.Error())
  }
  // x509
  pubInter,err := x509.ParsePKIXPublicKey(block.Bytes)
  if err != nil{
    _, file, line, _ := runtime.Caller(0)
    return false,util.Error(file,line+1,err.Error())
  }
  // assert
  pubKey := pubInter.(*ecdsa.PublicKey)
  hashText := sha256.Sum256(plainText)
  var r,s big.Int
  // unmarshal
  err = r.UnmarshalText(rText)
  if err != nil{
    _, file, line, _ := runtime.Caller(0)
    return false,util.Error(file,line+1,err.Error())
  }
  err = s.UnmarshalText(sText)
  if err != nil{
    _, file, line, _ := runtime.Caller(0)
    return false,util.Error(file,line+1,err.Error())
  }
  // verify
  ok := ecdsa.Verify(pubKey,hashText[:],&r,&s)
  return ok,nil
}

测试代码

  plainText := []byte("张华考上了北京大学;李萍进了中等技术学校;我在百货公司当售货员:我们都有美好的未来")
  rText,sText, _ := ECCSign(plainText,"./eccPrivate.pem")
  ok, err := ECCVerify(plainText,rText,sText,"./eccPublic.pem")
  fmt.Println(err)
  fmt.Printf("验证成功? %t",ok)

截图

2020062310470442.png

全部代码放到了gitee.com/frankyu365/gocrypto

参考

《现代密码学教程 谷利泽 杨义先等》

Go标准库-crypto/ecdsa

Go-标准库-crypto/sha256


相关文章
|
1月前
|
Go 索引
掌握Go语言:Go语言范围,优雅遍历数据结构,简化代码操作实战解析(24)
掌握Go语言:Go语言范围,优雅遍历数据结构,简化代码操作实战解析(24)
|
7月前
|
安全 Go
Go语言封装艺术:代码安全与结构清晰
Go语言封装艺术:代码安全与结构清晰
39 0
|
7月前
|
设计模式 编译器 Go
超实用!基于Go内嵌设计更优雅的代码
超实用!基于Go内嵌设计更优雅的代码
29 0
|
7月前
|
测试技术 Go
零代码上手测试:Go语言内置测试框架介绍
零代码上手测试:Go语言内置测试框架介绍
49 0
|
8月前
|
JSON 测试技术 Go
Go代码包与引入全解
Go代码包与引入全解
37 0
|
4月前
|
编译器 Go API
go generate指南:代码自动生成
go generate指南:代码自动生成
599 0
|
13天前
|
Go 微服务
4. 参考 go 代码——服务注册与发现
4. 参考 go 代码——服务注册与发现
|
1月前
|
安全 编译器 Serverless
掌握Go语言:深入Go语言常量:代码稳定的关键(10)
掌握Go语言:深入Go语言常量:代码稳定的关键(10)
|
7月前
|
Go 开发者
Go 语言怎么优化重复的 if err != nil 样板代码?
Go 语言怎么优化重复的 if err != nil 样板代码?
54 0
|
7月前
|
SQL 程序员 Go
Go语言微服务框架 - 7.Gormer-自动生成代码的初体验
作为一名程序员,我们总是希望能有更简单的开发方式来解决重复性的工作问题。在这个小版本中,我将结合自己的工作,来给出一套自动生成代码的完整方案,供大家借鉴。
41 0