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)
}
Go語言實現RSA數字簽名
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.