
生成公鑰和私鑰代碼
package utils
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
)
func GenRSAPubAndPri(bits int,filepath string ) error {
// 生成私鑰文件
privateKey, err := rsa.GenerateKey(rand.Reader, bits)
if err != nil {
return err
}
derStream := x509.MarshalPKCS1PrivateKey(privateKey)
priBlock := &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: derStream,
}
err= ioutil.WriteFile(filepath+"/private.pem",pem.EncodeToMemory(priBlock), 0644)
if err!=nil{
return err
}
fmt.Println("=======私鑰文件創建成功========")
// 生成公鑰文件
publicKey := &privateKey.PublicKey
derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
if err != nil {
return err
}
publicBlock := &pem.Block{
Type: "PUBLIC KEY",
Bytes: derPkix,
}
err= ioutil.WriteFile(filepath+"/public.pem",pem.EncodeToMemory(publicBlock), 0644)
if err!=nil{
return err
}
fmt.Println("=======公鑰文件創建成功=========")
return nil
}
調用上面代碼生成公鑰私鑰
package main
import (
"gomicro/utils"
"log"
)
func main() {
err := utils.GenRSAPubAndPri(1024, "./pem") //1024是長度,長度越長安全性越高,但是性能也就越差
if err != nil {
log.Fatal(err)
}
//執行完生成公鑰和私鑰,公鑰給別人私鑰給自己
}
使用私鑰去加密
package main
import (
"fmt"
"github.com/dgrijalva/jwt-go"
"io/ioutil"
"log"
)
type UserClaim struct { //這個結構體主要是用來宣示當前公鑰的使用者是誰,只有使用者和公鑰的簽名者是同一個人才可以用來正確的解密,還可以設置其他的屬性,可以去百度一下
Uname string `json:"username"`
jwt.StandardClaims //嵌套了這個結構體就實現了Claim接口
}
func main() {
priBytes, err := ioutil.ReadFile("./pem/private.pem")
if err != nil {
log.Fatal("私鑰文件讀取失敗")
}
pubBytes, err := ioutil.ReadFile("./pem/public.pem")
if err != nil {
log.Fatal("公鑰文件讀取失敗")
}
pubKey, err := jwt.ParseRSAPublicKeyFromPEM(pubBytes)
if err != nil {
log.Fatal("公鑰文件不正確")
}
priKey, err := jwt.ParseRSAPrivateKeyFromPEM(priBytes)
if err != nil {
log.Fatal("私鑰文件不正確")
}
token_obj := jwt.NewWithClaims(jwt.SigningMethodRS256, UserClaim{Uname: "xiahualou"}) //所有人給xiahualou發送公鑰加密的數據,但是只有xiahualou本人可以使用私鑰解密
token, _ := token_obj.SignedString(priKey)
uc := &UserClaim{}
getToken, _ := jwt.ParseWithClaims(token, uc, func(token *jwt.Token) (i interface{}, e error) { //使用私鑰解密
return pubKey, nil //這里的返回值必須是公鑰,不然解密肯定是失敗
})
if getToken.Valid { //服務端驗證token是否有效
fmt.Println(getToken.Claims.(*UserClaim).Uname)
}
}