1、數字簽名
公鑰:加密
私鑰:簽名
2、數字簽名的流程
消息認證問題的解決
1、數字簽名中不需要協商祕鑰,沒有配送需求
2、任何人都持有公鑰,都可以幫忙認證
3、私鑰只有發送方持有,無法進行抵賴
注意:簽名的數據不是數據本身,而是數據的哈希值
3、代碼實現
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
)
/*
私鑰簽名:
1、獲取私鑰,解析出私鑰內容
2、使用私鑰進行數字簽名
公鑰認證:
1、獲取公鑰,解析出公鑰內容
2、使用公鑰進行數字簽名認證
*/
func rsaSignData(filename string,src []byte)([]byte,error){
info , err := ioutil.ReadFile(filename)
if err != nil{
return nil,err
}
block,_ :=pem.Decode(info)
derText := block.Bytes
privateKey,err := x509.ParsePKCS1PrivateKey(derText)
if err != nil{
return nil,err
}
// PKCS#1 v1.5規定的RSASSA-PKCS1-V1_5-SIGN簽名方案計算簽名。注意hashed必須是使用提供給本函數的hash參數對(要簽名的)原始數據進行hash的結果。
// func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []byte) (s []byte, err error)
// 參數3:指定進行hash運算的算法
// 1、獲取hash值
hash := sha256.Sum256(src)
// 2、執行簽名操作
signature,err :=rsa.SignPKCS1v15(rand.Reader,privateKey,crypto.SHA256,hash[:])
if err != nil{
return nil,err
}
return signature,nil
}
func main(){
src := []byte("hello world")
signatrue , err := rsaSignData(privateKeyFile,src)
if err != nil{
fmt.Println("簽名失敗")
return
}
fmt.Printf("signatrue %x \n",signatrue)
err =verifySignature(signatrue,src,publicKeyFile)
if err != nil {
fmt.Println("驗證失敗!!!err:",err)
return
}
fmt.Println("簽名校驗成功!")
}
func verifySignature(sig,src []byte,filename string)error{
info , err := ioutil.ReadFile(filename)
if err != nil{
return err
}
block , _ := pem.Decode(info)
derText := block.Bytes
publicKey , err := x509.ParsePKCS1PublicKey(derText)
if err != nil{
return err
}
// 1、獲取hash值
hash := sha256.Sum256(src)
//func VerifyPKCS1v15(pub *PublicKey, hash crypto.Hash, hashed []byte, sig []byte) (err error)
//VerifyPKCS1v15認證RSA PKCS#1 v1.5簽名。hashed是使用提供的hash參數對(要簽名的)原始數據進行hash的結果。合法的簽名會返回nil,否則表示簽名不合法。
err =rsa.VerifyPKCS1v15(publicKey,crypto.SHA256,hash[:],sig)
return err
}