Go語言實現RSA數字簽名

package main
import (
	"os"
	"encoding/pem"
	"crypto/x509"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/rand"
	"crypto"
	"fmt"
)

//生成RSA私鑰和公鑰,保存到文件中
func GenerateRSAKey(bits int){
	//GenerateKey函數使用隨機數據生成器random生成一對具有指定字位數的RSA密鑰
	//Reader是一個全局、共享的密碼用強隨機數生成器
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err!=nil{
		panic(err)
	}
	//保存私鑰
	//通過x509標準將得到的ras私鑰序列化爲ASN.1 的 DER編碼字符串
	X509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)
	//使用pem格式對x509輸出的內容進行編碼
	//創建文件保存私鑰
	privateFile, err := os.Create("private.pem")
	if err!=nil{
		panic(err)
	}
	defer privateFile.Close()
	//構建一個pem.Block結構體對象
	privateBlock:= pem.Block{Type: "RSA Private Key",Bytes:X509PrivateKey}
	//將數據保存到文件
	pem.Encode(privateFile,&privateBlock)

	//保存公鑰
	//獲取公鑰的數據
	publicKey:=privateKey.PublicKey
	//X509對公鑰編碼
	X509PublicKey,err:=x509.MarshalPKIXPublicKey(&publicKey)
	if err!=nil{
		panic(err)
	}
	//pem格式編碼
	//創建用於保存公鑰的文件
	publicFile, err := os.Create("public.pem")
	if err!=nil{
		panic(err)
	}
	defer publicFile.Close()
	//創建一個pem.Block結構體對象
	publicBlock:= pem.Block{Type: "RSA Public Key",Bytes:X509PublicKey}
	//保存到文件
	pem.Encode(publicFile,&publicBlock)
}
//讀取RSA私鑰
func GetRSAPrivateKey(path string)*rsa.PrivateKey{
	//讀取文件內容
	file, err := os.Open(path)
	if err!=nil{
		panic(err)
	}
	defer file.Close()
	info, _ := file.Stat()
	buf:=make([]byte,info.Size())
	file.Read(buf)
	//pem解碼
	block, _ := pem.Decode(buf)
	//X509解碼
	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	return privateKey
}
//讀取RSA公鑰
func GetRSAPublicKey(path string)*rsa.PublicKey{
	//讀取公鑰內容
	file, err := os.Open(path)
	if err!=nil{
		panic(err)
	}
	defer file.Close()
	info, _ := file.Stat()
	buf:=make([]byte,info.Size())
	file.Read(buf)
	//pem解碼
	block, _ := pem.Decode(buf)
	//x509解碼
	publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err!=nil{
		panic(err)
	}
	publicKey := publicKeyInterface.(*rsa.PublicKey)
	return publicKey
}
//對消息的散列值進行數字簽名
func GetSign(msg []byte,path string)[]byte{
	//取得私鑰
	privateKey:=GetRSAPrivateKey(path)
	//計算散列值
	hash := sha256.New()
	hash.Write(msg)
	bytes := hash.Sum(nil)
	//SignPKCS1v15使用RSA PKCS#1 v1.5規定的RSASSA-PKCS1-V1_5-SIGN簽名方案計算簽名
	sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, bytes)
	if err!=nil{
		panic(sign)
	}
	return sign
}
//驗證數字簽名
func VerifySign(msg []byte,sign []byte,path string)bool{
	//取得公鑰
	publicKey:=GetRSAPublicKey(path)
	//計算消息散列值
	hash := sha256.New()
	hash.Write(msg)
	bytes := hash.Sum(nil)
	//驗證數字簽名
	err:=rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, bytes, sign)
	return err==nil
}

//測試RSA數字簽名
func main(){
	//生成密鑰文件
	GenerateRSAKey1(2048)

	//模擬發送方
	//要發送的消息
	msg:=[]byte("hello world")
	//生成簽名
	sign:=GetSign(msg,"private.pem")

	//模擬接收方
	//接受到的消息
	acceptmsg:=[]byte("hello world")
	//接受到的簽名
	acceptsign:=sign
	//驗證簽名
	result:=VerifySign(acceptmsg,acceptsign,"public.pem")
	fmt.Println("驗證結果:",result)
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章