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 frombase64.RawURLEncoding
tobase64.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 callDecodeString
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 = "CF-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 = "CF-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
Thank you, @encrylife