JWT token decoding even when the last character of the signature is changed

前端 未结 1 1040
滥情空心
滥情空心 2020-12-21 06:18

I was just trying out JWT tokens on a rails app, using this jwt library: https://github.com/jwt/ruby-jwt

JWT.encode({sss: \"333\"}, \'SECRET_KEY\')


        
相关标签:
1条回答
  • 2020-12-21 06:36

    The reason is the base64url encoding. The three parts of a JWT are all base64url encoded. Base64 encoding transforms the input data to a 6-Bit representation, mapped to a set of 64 ASCII characters. If you have 3 bytes source data, the base64 encoded result is 4 characters long, each character representing a 6 bit value, so 4 * 6 bits = 24 bits. If the number of bits that need to be encoded can't be divided by 6 without remainder, there'll be one character more with 2 or 4 insignificant bits.

    In your case, the encoded signature has 43 characters, which means 43 * 6 = 258 bits. So you could theoretically encode 258 bits, but the signature is only 256 bits (32 bytes) long, which means there are 2 insignificant bits on the end.

    A look on the base64 encoding table shows that 'A' to 'D' represent the 6 bit values 0 (000000) to 4 (000011), so the first four bits, which are still significant, are all identical, and only the last two, insignificant bits are changing. But the character 'E' stands for 5 (000100) and would change the last bit of the 256 bit value.

    If you're really concerned about the 2 bits on the end, you can consider to change the signature algorithm to HS384.

    Then you have a 384 bit (= 48 byte) hash, which is represented in 64 Base64 characters. 384 can be divided by 8 and by 6 without remainder, so there are no insignificant bits on the end and any change on the last character will lead to a failed verification.

    HS512 would have the same problem as HS256, and then even 4 insignificant bits on the end.

    Conclusion: it's all fine, nothing wrong here. You can change the algorithm, if you're worried, but I think it's not really necessary.

    0 讨论(0)
提交回复
热议问题