【问题标题】:JWT key is invalidJWT 密钥无效
【发布时间】:2017-12-02 14:47:03
【问题描述】:

我正在按照这个示例https://www.youtube.com/watch?v=eVlxuST7dCA 进行 jwt 身份验证。当我运行下面的代码时,出现“密钥无效”错误。当我尝试打印 tokenString 时,它是空的。此示例的 GitHub 是 https://github.com/potatogopher/jwt-go-example/blob/master/server.go 为什么会出现无效错误?

var privateKey []byte
privateKey, err := ioutil.ReadFile("demo.rsa")

token := jwt.New(jwt.GetSigningMethod("RS256"))
tokenString, err := token.SignedString(privateKey)

fmt.Println("TOKEN:", tokenString)

【问题讨论】:

  • 您确定 demo.rsa 是有效的密钥吗?
  • 无论您决定使用哪种签名方法,请确保将其硬编码并验证传入的 JWT 具有正确的签名方法。我不确定这是否仍然是 Go 中的漏洞,但请阅读本文以避免打开安全漏洞。 auth0.com/blog/…

标签: go web oauth jwt jwt-go


【解决方案1】:

我认为您所指的示例代码使用了 jwt-go 的过时 API。 RS256 签名方法要求密钥是rsa.PrivateKey,而不是字节缓冲区。这意味着,必须首先使用jwt.ParseRSAPrivateKeyFromPEM函数解析私钥。

我在下面更新了您的示例:

func main() {
    tokenString, err := createSignedTokenString()
    if err != nil {
        panic(err)
    }
    fmt.Printf("Signed token string:\n%v\n", tokenString)

    token, err := parseTokenFromSignedTokenString(tokenString)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Parsed token valid = %v, raw token:\n%v\n", token.Valid, token.Raw)
}

func createSignedTokenString() (string, error) {
    privateKey, err := ioutil.ReadFile("demo.rsa")
    if err != nil {
        return "", fmt.Errorf("error reading private key file: %v\n", err)
    }

    key, err := jwt.ParseRSAPrivateKeyFromPEM(privateKey)
    if err != nil {
        return "", fmt.Errorf("error parsing RSA private key: %v\n", err)
    }

    token := jwt.New(jwt.SigningMethodRS256)
    tokenString, err := token.SignedString(key)
    if err != nil {
        return "", fmt.Errorf("error signing token: %v\n", err)
    }

    return tokenString, nil
}

func parseTokenFromSignedTokenString(tokenString string) (*jwt.Token, error) {
    publicKey, err := ioutil.ReadFile("demo.rsa.pub")
    if err != nil {
        return nil, fmt.Errorf("error reading public key file: %v\n", err)
    }

    key, err := jwt.ParseRSAPublicKeyFromPEM(publicKey)
    if err != nil {
        return nil, fmt.Errorf("error parsing RSA public key: %v\n", err)
    }

    parsedToken, err := jwt.Parse(tokenString, 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 key, nil
    })
    if err != nil {
        return nil, fmt.Errorf("error parsing token: %v", err)
    }

    return parsedToken, nil
}

【讨论】:

  • @fhe-谢谢,它有效。之后我该如何解析?我试过 jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) 但我总是得到无效类型
  • @amanda45 我用 parseTokenFromSignedTokenString() 扩展了这个例子,它展示了如何验证一个签名的令牌字符串。在那里使用 rsa.PublicKey 很重要 :)
【解决方案2】:

您需要使用以下命令创建私钥:openssl genrsa -out demo.rsa

如果您不想这样做,您也可以使用 hmac 签名方法,您只需提供密钥/字符串。

例子:

key := []byte("test")

token := jwt.New(jwt.SigningMethodHS256)
tokenString, err := token.SignedString(key)

fmt.Println("TOKEN:", tokenString)

【讨论】:

  • 我确实创建了私钥。它和我的 go 文件在同一个文件夹中。
  • 就我而言,我将 jwt.SigningMethodES256 更改为 jwt.SigningMethodHS256。在 SignedString() 中使用 []byte(string)
猜你喜欢
  • 2015-03-28
  • 2020-09-25
  • 2017-01-27
  • 2019-12-25
  • 2021-12-20
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 2019-04-30
相关资源
最近更新 更多