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 mainimport ( "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}