Go语言使用椭圆曲线进行数字签名
2019-11-24 本文已影响0人
realguan
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/sha1"
"crypto/x509"
"encoding/pem"
"fmt"
"math/big"
"os"
)
func main() {
GenerateEccKey()
src := []byte("椭圆曲线进行数字签名")
rText,sText := EccSignature(src,"eccPrivate.pem")
bl := EccVerify(src,rText,sText,"eccPublic.pem")
fmt.Println(bl)
}
// 生成密钥对
func GenerateEccKey() {
// --------私钥写入磁盘--------
// 1 使用ecdsa生成密钥对
privateKey,err := ecdsa.GenerateKey(elliptic.P521(),rand.Reader)
if err != nil {
panic(err)
}
// 2 使用x509将私钥进行序列化
derText,err := x509.MarshalECPrivateKey(privateKey)
if err != nil {
panic(err)
}
// 3 将序列化后的字符串放入pem.Block结构体中
block := pem.Block{
Type:"ecdsa private key",
Bytes:derText,
}
// 4 使用pem编码
file,err := os.Create("eccPrivate.pem")
if err != nil {
panic(err)
}
pem.Encode(file,&block)
file.Close()
// --------公钥写入磁盘--------
// 1 从私钥中获取公钥
publicKey := privateKey.PublicKey
// 2 x509序列化公钥
derText,err = x509.MarshalPKIXPublicKey(&publicKey)
if err != nil {
panic(err)
}
// 3 将序列化后的字符串放入pem.Block 中
block = pem.Block{
Type:"ecdsa public key",
Bytes:derText,
}
// 4 使用pem编码
file,err = os.Create("eccPublic.pem")
if err != nil {
panic(err)
}
pem.Encode(file,&block)
file.Close()
}
// ecdsa 签名
func EccSignature(plainText []byte,privName string) (rText,sText []byte) {
// 1 打开私钥将内容读取出来
file,err := os.Open(privName)
if err != nil {
panic(err)
}
fileInfo,err := file.Stat()
if err != nil {
panic(err)
}
buf := make([]byte,fileInfo.Size())
file.Read(buf)
file.Close()
// 2 pem解码
block,_ := pem.Decode(buf)
// 3 x509解析
privateKey,err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
panic(err)
}
// 4 对原始数据进行hash运算得到散列值
hashText := sha1.Sum(plainText)
// 5 进行数据签名
r,s,err := ecdsa.Sign(rand.Reader,privateKey,hashText[:])
if err != nil {
panic(err)
}
// 6 对r,s内存中的数据进行格式化
rText,err = r.MarshalText()
if err != nil {
panic(err)
}
sText,err = s.MarshalText()
if err != nil {
panic(err)
}
return
}
// ecdsa签名认证
func EccVerify(plainText,rText,sText []byte,pubFile string) bool {
// 1 打开公钥文件,将内容读取出来
file,err := os.Open(pubFile)
if err != nil {
panic(err)
}
fileInfo,err := file.Stat()
if err != nil {
panic(err)
}
buf := make([]byte,fileInfo.Size())
file.Read(buf)
file.Close()
// 2 pem解码
block,_ := pem.Decode(buf)
// 3 x509解析
pubInterface,err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
panic(err)
}
// 4 类型断言获取公钥
publicKey := pubInterface.(*ecdsa.PublicKey)
// 5 对原始数据进行hash运算得到散列值
hashText := sha1.Sum(plainText)
// 6 签名认证
// 将rText,sText 转换成 int
var r,s big.Int
r.UnmarshalText(rText)
s.UnmarshalText(sText)
bl := ecdsa.Verify(publicKey,hashText[:],&r,&s)
return bl
}