天天看點

Go-ecc數字簽名詳解與代碼Ecc簽名的Go實作截圖參考

目錄

  • Ecc簽名的Go實作
    • crypto/ecdsa包
    • 簽名
    • 驗證簽名
    • 測試代碼
  • 截圖
  • 參考

在Go-數字簽名詳解與Rsa數字簽名代碼中已經講了數字簽名的原理,就不重複了

Ecc簽名的Go實作

crypto/ecdsa包

使用私鑰對任意長度的hash值(必須是較大資訊的hash結果)進行簽名,傳回簽名結果(一對大整數)。私鑰的安全性取決于密碼讀取器的熵度(随機程度)。

使用公鑰驗證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)
           

截圖

Go-ecc數字簽名詳解與代碼Ecc簽名的Go實作截圖參考

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

參考

《現代密碼學教程 谷利澤 楊義先等》

Go标準庫-crypto/ecdsa

Go-标準庫-crypto/sha256