代码之家  ›  专栏  ›  技术社区  ›  unuser

JWT得到验证,即使我更改了其中的一个字符[重复]

  •  1
  • unuser  · 技术社区  · 1 年前

    我正在学习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无法得到验证?

    2 回复  |  直到 1 年前
        1
  •  1
  •   zerkms    1 年前

    HS256 使用256位长的签名。

    当256位以64为基数编码时,您最终会得到: PX1fXhDusE5JC3cvktPsO0jEw6kGe-NKa-PiSmYpu70 .

    它有43个字符长。43 x 6=258

    这意味着最后2位未使用。

    这意味着你可以 0 , 1 , 2 3 在那里,它仍然是一个有效的令牌。

        2
  •  -1
  •   Mahendran R    1 年前

    我希望问题是,jwt代币是基于到期时间有效的。即使您更改了密钥,最终的令牌也会被修改,但它确实是一个有效的令牌。也许,如果你想使用它进行类似身份验证的登录,你应该将其存储在DB或本地存储等中,以访问其他文件。