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




  • 相关阅读:
    如何计算出OS/400中有多少个Library
    不就是SELECT COUNT语句吗,竟然能被面试官虐的体无完肤
    Shiro + JWT + Spring Boot Restful 简易教程
    面试突击86:SpringBoot 事务不回滚?怎么解决?
    大聪明教你学Java | Spring Boot 使用自定义注解实现防止表单重复提交
    前端取消请求与取消重复请求
    SQL 子查询怎么优化?写的很深的这种!
    springboot 防止重复提交
    SpringBoot 实现 excel 全自由导入导出,性能强的离谱,用起来还特优雅
    「前端每日一问(51)」什么是运行时和编译时?
  • 原文地址:https://www.cnblogs.com/hualou/p/12090813.html
Copyright © 2020-2023  润新知