在Golang中验证JWT令牌失败

huangapple go评论76阅读模式
英文:

Verify JWT Token fails in Golang

问题

我有一个在Node.js应用程序中生成的JWT令牌,使用HS256进行签名。我已经编写了用于在Golang中验证它的代码。即使我在JWT.io网站上验证过了,但我收到了一个"签名无效"的错误消息。
该代码还验证了公钥/私钥,但这部分是正常工作的。只有HS256不正常。
我还打印了令牌和密钥,以确保它们是正确的值。
任何帮助将不胜感激。
我的Golang代码:

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
	// 验证算法是否是预期的算法:
	if conf.JwtAlgorithm != token.Header["alg"] {
		log.Printf("unexpected signing method: %s, conf algorithm: %s\n", token.Header["alg"], conf.JwtAlgorithm)
		return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
	}

	log.Printf("JWT algo is: %s, Public is %s, secret is %s", token.Header["alg"], publicKey, secret)

	if secret != "" {
		log.Printf("Returning secret %s", secret)
		return []byte(secret), nil
	}
	if publicKey != "" {
		pub, _ := jwt.ParseRSAPublicKeyFromPEM([]byte(publicKey))
		fmt.Println("pub is of type RSA:", pub)
		return pub, nil
	}
	return nil, fmt.Errorf("PublicKey and secret are empty")
})
英文:

I have a JWT token generated in nodejs app. It is signed using HS256. I've written the code to validate it in golang. I get an error message of "signature is invalid" even though I verified it in the JWT.io site.
The code validates also Public/Private, but this works. Only the HS256 is not
I've also printed the token and the secret to make sure they are the right values.
Any help will be appreciated.
My golang code:

token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		// Validate the alg is the expected algorithm:
		if conf.JwtAlgorithm != token.Header["alg"] {
			log.Printf("unexpected signing method: %s, conf algorithm: %s\n", token.Header["alg"], conf.JwtAlgorithm)
			return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
		}

		log.Printf("JWT algo is: %s, Public is %s, secret is %s", token.Header["alg"], publicKey, secret)

		if secret != "" {
			log.Printf("Returning secret %s", secret)
			return []byte(secret), nil
		}
		if publicKey != "" {
			pub, _ := jwt.ParseRSAPublicKeyFromPEM([]byte(publicKey))
			fmt.Println("pub is of type RSA:", pub)
			return pub, nil
		}
		return nil, fmt.Errorf("PublicKey and secret are empty")
	})

答案1

得分: 1

由于您只有一个HMAC密钥,您需要像这样的代码:

package main

import (
	"log"

	"github.com/golang-jwt/jwt/v4"
)

func main() {
	const tokenString = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.drt_po6bHhDOF_FJEHTrK-KD8OGjseJZpHwHIgsnoTM"

	var keyfunc jwt.Keyfunc = func(token *jwt.Token) (interface{}, error) {
		return []byte("mysecret"), nil
	}

	parsed, err := jwt.Parse(tokenString, keyfunc)
	if err != nil {
		log.Fatalf("Failed to parse JWT.\nError: %s", err.Error())
	}

	if !parsed.Valid {
		log.Fatalln("Token is not valid.")
	}

	log.Println("Token is valid.")
}

jwt.Keyfunc的返回类型确实令人困惑。对于HMAC密钥,返回类型应为[]byte

请注意,HMAC密钥不使用公钥密码学,因此只是一个不应该共享的私钥。

如果您需要解析和验证的JWT变得更加复杂,请查看这个包:github.com/MicahParks/keyfunc。它支持多个给定的密钥,如HMAC和远程JWKS资源。

英文:

Since you only have a single HMAC key, you'll want something like this:

package main

import (
	"log"

	"github.com/golang-jwt/jwt/v4"
)

func main() {
	const tokenString = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.drt_po6bHhDOF_FJEHTrK-KD8OGjseJZpHwHIgsnoTM"

	var keyfunc jwt.Keyfunc = func(token *jwt.Token) (interface{}, error) {
		return []byte("mysecret"), nil
	}

	parsed, err := jwt.Parse(tokenString, keyfunc)
	if err != nil {
		log.Fatalf("Failed to parse JWT.\nError: %s", err.Error())
	}

	if !parsed.Valid {
		log.Fatalln("Token is not valid.")
	}

	log.Println("Token is valid.")
}

It's certainly confusing what the return type should be for a jwt.Keyfunc. For an HMAC key, the return type should be []byte.

Please note that HMAC keys do not use public key cryptography and therefore are only a private key that shouldn't be shared.

If the JWTs you need to parse and verify start to become more complex, check out this package: github.com/MicahParks/keyfunc. It has support for multiple given keys like HMAC and remote JWKS resources.

huangapple
  • 本文由 发表于 2022年3月6日 18:08:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/71369336.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定