douyuanliao8815 2015-07-02 22:08
浏览 246

golang JWT没有签名。 “ crypto / rsa:验证错误”

I'm using JWT. This is how I create the token.

func createToken(user User) (string, error) {
    token := jwt.New(jwt.GetSigningMethod("RS256"))

    token.Claims["Name"] = user.Name
    token.Claims["Email"] = user.Email
    //token.Claims["ExpDate"] = time.Now().Add(time.Hour * 1).Unix()

    tokenString, err := token.SignedString([]byte(config.PrivateKey))
    if err != nil {
        return "", err
    }

    return tokenString, nil
}

This is how I verify the token.

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {    
        return []byte(config.PublicKey), nil
    })

I generated my public and private keys with this python code

from Crypto.PublicKey import RSA

private = RSA.generate(1024)
public  = private.publickey()

priv = private.exportKey()
pub = public.exportKey()

I get crypto/rsa: verification error. When I print the parsed token everything looks fine except token.Valid which is false and token.Signature is empty.

type Token struct {
    Raw       string                 // The raw token.  Populated when you Parse a token
    Method    SigningMethod          // The signing method used or to be used
    Header    map[string]interface{} // The first segment of the token
    Claims    map[string]interface{} // The second segment of the token
    Signature string                 // The third segment of the token.  Populated when you Parse a token
    Valid     bool                   // Is the token valid?  Populated when you Parse/Verify a token
}

tokenString--> eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJFbWFpbCI6InRlc3RAaG90bWFpbC5jb20iLCJOYW1lIjoidGVzdE5hbWUifQ.fgd1h4LB1zzAiPFLKMOJrQu12rTLeXBDKHdnqiNc04NRn-1v7cHEQpDNawvScMIGrcQLbZo6WrldZQT9ImYWpUyy3CcD2uMO95I5PN6aXOSPb26nNGQpmIi1HNZrq5359hKZ6BWEJnW9iTg7RgmMvZGmIqlGLsOY2a6UiiwBsI0
token.Raw--> eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJFbWFpbCI6InRlc3RAaG90bWFpbC5jb20iLCJOYW1lIjoidGVzdE5hbWUifQ.fgd1h4LB1zzAiPFLKMOJrQu12rTLeXBDKHdnqiNc04NRn-1v7cHEQpDNawvScMIGrcQLbZo6WrldZQT9ImYWpUyy3CcD2uMO95I5PN6aXOSPb26nNGQpmIi1HNZrq5359hKZ6BWEJnW9iTg7RgmMvZGmIqlGLsOY2a6UiiwBsI0
token.Header--> map[alg:RS256 typ:JWT]
token.Claims--> map[Email:test@hotmail.com Name:testName]
token.Signature-->           
token.Valid--> false

PS: I don't have any SSL-Certificates.

  • 写回答

1条回答 默认 最新

  • duanqianmou4661 2016-12-06 05:23
    关注

    This worked for me. I generated the private.pem and public.pem using these commands.

    openssl genrsa -des3 -out private.pem 1024
    openssl rsa -in private.pem -outform PEM -pubout -out public.pem
    

    Code:

    package main
    
    import (
        "fmt"
        "github.com/dgrijalva/jwt-go"
        "io/ioutil"
        "log"
        "time"
    )
    
    //Claims can have user id.. etc for Identification purpose
    type AppClaims struct {
        UserId string `json:"userId"`
        jwt.StandardClaims
    }
    
    var (
        privateKey []byte
        publicKey  []byte
        err        error
    )
    
    const (
        longForm = "Jan 2, 2006 at 3:04pm (MST)"
    )
    
    func errLog(err error) {
        if err != nil {
            log.Fatal("Error:", err.Error())
        }
    }
    
    func init() {
        privateKey, err = ioutil.ReadFile("../private.pem")
        errLog(err)
        publicKey, err = ioutil.ReadFile("../public.pem")
        errLog(err)
    }
    
    func jwtTokenGen() (interface{}, error) {
        privateRSA, err := jwt.ParseRSAPrivateKeyFromPEM(privateKey)
        if err != nil {
            return nil, err
        }
        claims := AppClaims{
            "RAJINIS*",
            jwt.StandardClaims{
                ExpiresAt: time.Now().Add(time.Minute * 15).Unix(),
                Issuer:    "test",
            },
        }
        token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
        ss, err := token.SignedString(privateRSA)
        return ss, err
    }
    
    func jwtTokenRead(inToken interface{}) (interface{}, error) {
        publicRSA, err := jwt.ParseRSAPublicKeyFromPEM(publicKey)
        if err != nil {
            return nil, err
        }
        token, err := jwt.Parse(inToken.(string), func(token *jwt.Token) (interface{}, error) {
            if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
                return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
            }
            return publicRSA, err
        })
    
        if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid {
            return claims, nil
        } else {
            return nil, err
        }
    }
    
    func getTokenRemainingValidity(timestamp interface{}) int {
        expireOffset := 0
        if validity, ok := timestamp.(float64); ok {
            tm := time.Unix(int64(validity), 0)
            remainder := tm.Sub(time.Now())
            if remainder > 0 {
                fmt.Println(remainder)
                return int(remainder.Seconds()) + expireOffset
            }
        }
        return expireOffset
    }
    
    func main() {
        signedString, err := jwtTokenGen()
        fmt.Println(signedString, err)
        claims, err := jwtTokenRead(signedString)
        if err != nil {
            errLog(err)
        }
        claimValue := claims.(jwt.MapClaims)
        fmt.Println(claimValue["iss"], claimValue["exp"], claimValue["userId"])
        //  t, _ := time.Parse(longForm, string(claimValue["exp"].(float64)))
        fmt.Println(getTokenRemainingValidity(claimValue["exp"]))
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度