golang-jwt / jwt

Go implementation of JSON Web Tokens (JWT).

Home Page:https://golang-jwt.github.io/jwt/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

token signature is invalid: signature is invalid

encrylife opened this issue · comments

When I use golang-jwt with java generate token ,it always report token signature is invalid: signature is invalid. I try use base64 decode the secret before use the same secret.But it report other issues. The code as below:

func ParseToken(token string) (*JsonWebTokenCustomerClaim, error) {
tokenClaims, err := jwt.ParseWithClaims(token, &JsonWebTokenCustomerClaim{}, func(token *jwt.Token) (interface{}, error) {
var key = fmt.Sprintf("%s", GetV("jwt.key"))
return []byte(key), nil
/var mySignKey = "CF-JaNdRgUkXn2r5u8x/A?D(G+KbPeShVmYq3s6v9y$B&E)H@McQfTjWnZr4u7w"

	decodeString, err := base64.RawStdEncoding.DecodeString(mySignKey)
	if err != nil {
		return nil, err
	} // stil error but it report from base 64 when I change the secret in order to the base64 work will it report the other problem : invalid token.
	return decodeString, nil*/
})
if err != nil {
	return nil, err
}

if tokenClaims != nil {
	if claims, ok := tokenClaims.Claims.(*JsonWebTokenCustomerClaim); ok && tokenClaims.Valid {
		return claims, nil
	}
}

return nil, err

}

I caught same situation. it is would be possible as Encode Segment(is) generated base64 signature loans with padding, but in base RawURLEncoding configure with URLEncoding.WithPadding(NoPadding). My signature was 42 length, but base64 decode cut last byte and signature was be invalid.

my signature was: 4G4Qq__PqkC2MupBR0cpHNaqlAxt4SfnD0ncQi3bwI

Hey, @oxisto do you have any idea to fix it?

There's a ParserOption that allows enabling padding, does this help?

https://pkg.go.dev/github.com/golang-jwt/jwt/v5#WithPaddingAllowed

There's a ParserOption that allows enabling padding, does this help?

https://pkg.go.dev/github.com/golang-jwt/jwt/v5#WithPaddingAllowed

try it but still report error

Nope, it is doesn't help, because with option added = two symbols at the and of base64 decoded string and changed encoding from base64.RawURLEncoding to base64.URLEncoding at the next method.

func (p *Parser) DecodeSegment(seg string) ([]byte, error)

For example result on my data, 4G4Qq__PqkC2MupBR0cpHNaqlAxt4SfnD0ncQi3bwI== with padding options for Parse method. When we call DecodeString outputlen of slice bites was 33 symbols, but calculated signature on my datas expected length of 32 bytes. I called without WithPaddingAllowed in Parse
and gave 31 bytes of decoded signature (:

My parse method

sectet := ""// some secret slice bytes

token, err := jwt.Parse(data, func(token *jwt.Token) (interface{}, error) {
  if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
	  return nil, fmt.Errorf("signing method %s", token.Header["alg"])
  }

  return secret, nil
}, jwt.WithPaddingAllowed()) // changed option for parse with padding
if err != nil {
  return nil, err
}

Nope, it is doesn't help, because with option added = two symbols at the and of base64 decoded string and changed encoding from base64.RawURLEncoding to base64.URLEncoding at the next method.

func (p *Parser) DecodeSegment(seg string) ([]byte, error)

For example result on my data, 4G4Qq__PqkC2MupBR0cpHNaqlAxt4SfnD0ncQi3bwI== with padding options for Parse method. When we call DecodeString outputlen of slice bites was 33 symbols, but calculated signature on my datas expected length of 32 bytes. I called without WithPaddingAllowed in Parse and gave 31 bytes of decoded signature (:

My parse method

sectet := ""// some secret slice bytes

token, err := jwt.Parse(data, func(token *jwt.Token) (interface{}, error) {
  if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
	  return nil, fmt.Errorf("signing method %s", token.Header["alg"])
  }

  return secret, nil
}, jwt.WithPaddingAllowed()) // changed option for parse with padding
if err != nil {
  return nil, err
}

my method is :
`token, err := jwt.ParseWithClaims(tokenString, &JsonWebTokenCustomerClaim{}, func(token jwt.Token) (interface{}, error) {
key = "CFJaNdRgUkXn2r5u8xADGKbPeShVmYq3s6v9yBEHMcQfTjWnZr4u7w"
key = "C
F-JaNdRgUkXn2r5u8x/A?D(G+KbPeShVmYq3s6v9y$B&E)H@McQfTjWnZr4u7w"

	bytes := []byte(key)

	return bytes, nil

}, jwt.WithPaddingAllowed())`

`
token, err := jwt.ParseWithClaims(tokenString, &JsonWebTokenCustomerClaim{}, func(token jwt.Token) (interface{}, error) {
key = "CFJaNdRgUkXn2r5u8xADGKbPeShVmYq3s6v9yBEHMcQfTjWnZr4u7w"
key = "C
F-JaNdRgUkXn2r5u8x/A?D(G+KbPeShVmYq3s6v9y$B&E)H@McQfTjWnZr4u7w"
dec, e := base64.URLEncoding.DecodeString(key)
//d, e := base64.NewEncoding("~!@#$%^&()ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/").DecodeString(key)
if e != nil {
fmt.Println(e.Error())
}

	return dec, nil

}, jwt.WithPaddingAllowed())

`
does not work, report : illegal base64 data at input byte 1.If I use base64.…… decode(),it will report illegal base64 data input ,if I direct return []byte(key),it report signature or token is invalid

This is impossible to debug unless we know how these tokens or signature are generated. For me this seems to be a misconfiguration on the encoding side and possibly a wrong key. The RFC states that the token/signature should be generated using Base64URLEncoding without padding. We offer the WithPaddingAllowed as a sort of workaround but it is not recommended nor really "supported" as it's against the standard.

My guess there are probably two different issues here, one is possibly a key mismatch (or the key in the wrong format) and one is an token encoding issue. We need the key in raw bytes, so if the string you pasted before is the base64 version of your key then base64 decoding it first should look like it should work @encrylife

Actually CF-JaNdRgUkXn2r5u8x/A?D(G+KbPeShVmYq3s6v9y$B&E)H@McQfTjWnZr4u7w doesn't look like its base64 but already the raw byte sequence, so just returning it with []byte(key) should work and the error is probably somewhere else..

Thanks ,It work will now.I compare the generated string,then I found the problem,the key is wrong,it used the key is a middle product,not the init key. @oxisto

i generated signature with SigningMethodHS256 and used random token string which transform to []byte(token). Are We need use only base64 string as a secret key?

i generated signature with SigningMethodHS256 and used random token string which transform to []byte(token). Are We need use only base64 string as a secret key?

At first,if you use golang-jwt only ,you not need the base64 string ,you can use any generated string.But if you develop it with one languages generated the token,and use the another language parse, I recommend you use the base64 string