美文网首页
Go Jwt Token 使用 RSA256 签名

Go Jwt Token 使用 RSA256 签名

作者: 三梦哥 | 来源:发表于2023-11-04 16:51 被阅读0次

    在 Go 语言中使用 Jwt Token ,我们采用更加安全的RAS256方式进行签名。使用私钥进行签发 Token,使用公钥进行签名验证。

    生成密钥对

    在项目根目录下面创建 Makefile文件,填充下面的内容:

    .PHONY: cert-private cert-public
    cert-private:
        @openssl genrsa -out cert/id_rsa 4096
    cert-public:
        @openssl rsa -in cert/id_rsa -pubout -out cert/id_rsa_2.pub
    

    在 Shell 中执行:

    make cert-private && make cert-public
    

    来生成对应的私钥和公钥

    使用下面的代码来创建main.go 文件:

    package main
    
    import (
        "bytes"
        "fmt"
        "log"
        "os"
        "time"
    
        "github.com/golang-jwt/jwt/v5"
        "github.com/google/uuid"
    )
    
    var (
        privateKey *bytes.Buffer
        publicKey  *bytes.Buffer
    )
    
    func generateToken() (string, error) {
        key, err := jwt.ParseRSAPrivateKeyFromPEM(privateKey.Bytes())
        if err != nil {
            return "", err
        }
        now := time.Now().UTC()
        claims := jwt.RegisteredClaims{
            IssuedAt:  jwt.NewNumericDate(now),
            ID:        uuid.NewString(),
            ExpiresAt: jwt.NewNumericDate(now.Add(10 * time.Minute)),
        }
        token, err := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(key)
        if err != nil {
            return "", err
        }
        return token, nil
    }
    
    func validate(token string) (map[string]interface{}, error) {
        key, err := jwt.ParseRSAPublicKeyFromPEM(publicKey.Bytes())
        if err != nil {
            return nil, err
        }
        parsed, err := jwt.Parse(token, func(jwtToken *jwt.Token) (interface{}, error) {
            if _, ok := jwtToken.Method.(*jwt.SigningMethodRSA); !ok {
                return nil, fmt.Errorf("unexpected method:%s", jwtToken.Header["alg"])
            }
            return key, nil
        })
        if err != nil {
            return nil, err
        }
    
        claims, ok := parsed.Claims.(jwt.MapClaims)
        if !ok || !parsed.Valid {
            return nil, fmt.Errorf("invalid token:%w", err)
        }
        return claims, nil
    }
    
    func main() {
        prKey, err := os.ReadFile("cert/id_rsa")
        if err != nil {
            log.Fatal(err)
        }
        privateKey = bytes.NewBuffer(prKey)
    
        pubKey, err := os.ReadFile("cert/id_rsa.pub")
        if err != nil {
            log.Fatal(err)
        }
        publicKey = bytes.NewBuffer(pubKey)
        token, err := generateToken()
        if err != nil {
            log.Fatal(err)
        }
        log.Printf("token:%s", token)
        m, err := validate(token)
        if err != nil {
            log.Fatal(err)
        }
        log.Printf("token claims:%v", m)
    }
    
    

    编译执行:

    go run main.go
    

    生成的 Token 可以在jwt.io网站上进行查看,使用公钥进行签名校验,如图:

    image.png

    相关文章

      网友评论

          本文标题:Go Jwt Token 使用 RSA256 签名

          本文链接:https://www.haomeiwen.com/subject/zbvaidtx.html