我正在学习JWT。我使用Golang来签署和验证JWT。问题是,当我将已签名JWT的最后一个字符更改为另一个字符时,它仍然会得到验证。
例如
以下是我的验证方法:
func verify(tokenString字符串,hmacSampleSecret[]字节){
parsedToken, _ := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
}
return hmacSampleSecret, nil
})
if claims, ok := parsedToken.Claims.(jwt.MapClaims); ok && parsedToken.Valid {
fmt.Println("Token is valid")
fmt.Println("Claims:", claims)
} else {
fmt.Println("Invalid token")
}
}
以及签名方式:
func sign(hmacSampleSecret []byte) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"foo": "bar",
"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
})
tokenString, _ := token.SignedString(hmacSampleSecret)
fmt.Println(tokenString)
/*
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJmb28iOiJiYXIiLCJuYmYiOjE0NDQ0Nzg0MDB9.
sO0jEw6kGe-NKa-PiSmYpu70
*/
verify(tokenString, hmacSampleSecret) // validated
modifiedToken := tokenString[:len(tokenString)-1] + "1"
fmt.Println(modifiedToken)
/*
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJmb28iOiJiYXIiLCJuYmYiOjE0NDQ0Nzg0MDB9.
sO0jEw6kGe-NKa-PiSmYpu71
*/
verify(modifiedToken, hmacSampleSecret) // validated
}
我刚刚将“0”更改为“1”,它仍然会得到验证。
我的秘密是:[]字节(“8e94e9111b74b6f22f59a7f8a4e3c3a0”)
之后,我将声明更改为:
claims := jwt.MapClaims{
"foo": "bar",
"nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(),
"jti": uuid.NewString(),
"iat": time.Now().Unix(),
"exp": time.Now().Add(time.Hour * 1).Unix(),
"iss": "issuer",
}
即使最后一个字符被更改,它也不再被验证。是什么导致了这种情况,是标题、声明还是秘密?如何确保未签名的JWT无法得到验证?