1.生成秘钥对并写入磁盘文件
1.应用ecdsa生成秘钥对
2.将私钥写入磁盘
- 应用x509进行反序列化
- 将失去的切片字符串放到pem.Block构造体中
- 应用pem编码
3.将公钥写入磁盘
- 从私钥中失去公钥
- 应用x509进行序列化
- 将失去的切片字符串放入pem.Block构造体中
- 应用pem编码
2.应用私钥进行数字签名
1.关上私钥文件,将内容读出来
2.应用pem进行数据解码
3.应用x509对数据还原
4.对原始数据进行哈希运算
5.进行数字签名
func Sign(rand io.Reader, priv PrivateKey, hash []byte) (r, s big.Int, err error)
6.返回值为指针,因而须要将该地址指向内存中的数据进行序列话
3.应用公钥验证数字签名
1.关上公钥文件,读出数据
2.应用pem进行解码
3.应用x509进行公钥数据还原
func ParsePKIXPublicKey(derBytes []byte) (pub interface{}, err error)4.因为上一步返回的是一个接口类型,因而须要进行类型断言,将接口类型转换为公钥
5.对原始数据进行哈希运算
6.验签
4.go中利用
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"encoding/pem"
"os"
"crypto/sha256"
"math/big"
)
func GenerateEcdsaKey () {
//1.应用ecdsa生成秘钥对
privateKey, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
if err != nil {
panic(err)
}
//2.将私钥写入磁盘
//* 应用x509进行反序列化
ecPrivateKey, err := x509.MarshalECPrivateKey(privateKey)
if err != nil {
panic(err)
}
//* 将失去的切片字符串放到pem.Block构造体中
block := pem.Block{
Type: "ecdsa private key",
Headers: nil,
Bytes: ecPrivateKey,
}
//* 应用pem编码
file, err := os.Create("ecPrivate.pem")
if err != nil {
panic(err)
}
defer file.Close()
err = pem.Encode(file, &block)
if err != nil {
panic(err)
}
//3.将公钥写入磁盘
//* 从私钥中失去公钥
publicKey := privateKey.PublicKey
//* 应用x509进行序列化
ecPublicKey, err := x509.MarshalPKIXPublicKey(&publicKey)
if err != nil {
panic(err)
}
//* 将失去的切片字符串放入pem.Block构造体中
block = pem.Block{
Type: "ecdsa public key",
Headers: nil,
Bytes: ecPublicKey,
}
//* 应用pem编码
file, err = os.Create("ecPublic.pem")
if err != nil {
panic(err)
}
defer file.Close()
pem.Encode(file, &block)
}
//签名
func SignECDSA (plainText []byte, priFileName string) (rText, sText []byte) {
//1.关上私钥文件,将内容读出来
file, err := os.Open(priFileName)
if err != nil {
panic(err)
}
defer file.Close()
fileInfo, err := file.Stat()
if err != nil {
panic(err)
}
buf := make([]byte, fileInfo.Size())
_, err = file.Read(buf)
if err != nil {
panic(err)
}
//2.应用pem进行数据解码
block, _ := pem.Decode(buf)
//3.应用x509对数据还原
privateKey, err := x509.ParseECPrivateKey(block.Bytes)
if err != nil {
panic(err)
}
//4.对原始数据进行哈希运算
hashText := sha256.Sum256(plainText)
//5.进行数字签名
var r, s *big.Int //留神这里
r, s, err = ecdsa.Sign(rand.Reader, privateKey, hashText[:])
if err != nil {
panic(err)
}
//6.返回值为指针,因而须要将该地址指向内存中的数据进行序列话
rText, err = r.MarshalText()
if err != nil {
panic(err)
}
sText, err = s.MarshalText()
if err != nil {
panic(err)
}
return rText,sText
}
//验签
func VerifyECDSA (plainText, rText, sText []byte, pubFileName string) bool {
//1.关上公钥文件,读出数据
file, err := os.Open(pubFileName)
if err != nil {
panic(err)
}
defer file.Close()
fileInfo, err := file.Stat()
if err != nil {
panic(err)
}
buf := make([]byte, fileInfo.Size())
_, err = file.Read(buf)
if err != nil {
panic(err)
}
//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.对原始数据进行哈希运算
hashText := sha256.Sum256(plainText)
//6.验签
var r, s big.Int
r.UnmarshalText(rText)
s.UnmarshalText(sText)
res := ecdsa.Verify(publicKey, hashText[:], &r, &s)
return res
}
发表回复