28.Jwt集成(2):生成公私鑰、非對稱加密生成和解析token


生成公鑰和私鑰代碼

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)
    }

}





免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM