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

。_饼干妹妹 提交于 2020-02-24 05:33:28

问题


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')

returns below token:

eyJhbGciOiJIUzI1NiJ9.eyJzc3MiOiIzMzMifQ.CwX_1FztYHVpyx_G27u938SceilsVc5AB5Akwqlo2HA

Then I decoded using the above token

JWT.decode("eyJhbGciOiJIUzI1NiJ9.eyJzc3MiOiIzMzMifQ.CwX_1FztYHVpyx_G27u938SceilsVc5AB5Akwqlo2HA", 'SECRET_KEY')

returns below response correctly:

[{"sss"=>"333"}, {"alg"=>"HS256"}]

But if I try to change the last letter of the token to B instead of current A it is still returning the same response which is weird.

JWT.decode("eyJhbGciOiJIUzI1NiJ9.eyJzc3MiOiIzMzMifQ.CwX_1FztYHVpyx_G27u938SceilsVc5AB5Akwqlo2HB", 'SECRET_KEY')

Getting this response even though the token I provided is wrong:

[{"sss"=>"333"}, {"alg"=>"HS256"}]

Actually I am getting the same response for all characters up to 'D'

If I use F and others above then its showing error as expected:

JWT.decode("eyJhbGciOiJIUzI1NiJ9.eyJzc3MiOiIzMzMifQ.CwX_1FztYHVpyx_G27u938SceilsVc5AB5Akwqlo2HF", 'SECRET_KEY')

JWT::VerificationError (Signature verification raised) from (irb):34

What could be the reason for this? Is it the expected behavior or am I doing something wrong here?


回答1:


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.

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 byte) 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.

Conclusion: it's all fine, nothing wrong here, it works as expected.



来源:https://stackoverflow.com/questions/58492009/jwt-token-decoding-even-when-the-last-character-of-the-signature-is-changed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!