Go-ecc数字签名详解与代码
Posted lady_killer9
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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)
截图
全部代码放到了gitee.com/frankyu365/gocrypto
参考
《现代密码学教程 谷利泽 杨义先等》
Go标准库-crypto/ecdsa
Go-标准库-crypto/sha256
以上是关于Go-ecc数字签名详解与代码的主要内容,如果未能解决你的问题,请参考以下文章