我只是使用以下jwt库在Rails应用程序上尝试JWT令牌: https://github.com/jwt/ruby-jwt
JWT.encode({sss: "333"}, 'SECRET_KEY')
返回以下令牌:
eyJhbGciOiJIUzI1NiJ9.eyJzc3MiOiIzMzMifQ.CwX_1FztYHVpyx_G27u938SceilsVc5AB5Akwqlo2HA
然后我使用上述令牌进行了解码
JWT.decode("eyJhbGciOiJIUzI1NiJ9.eyJzc3MiOiIzMzMifQ.CwX_1FztYHVpyx_G27u938SceilsVc5AB5Akwqlo2HA", 'SECRET_KEY')
正确返回以下响应:
[{“ sss” =>“ 333”},{“ alg” =>“ HS256”}]
但是,如果我尝试将令牌的最后一个字母更改为 B 而不是当前的 A ,它仍会返回相同的响应,很奇怪。
JWT.decode("eyJhbGciOiJIUzI1NiJ9.eyJzc3MiOiIzMzMifQ.CwX_1FztYHVpyx_G27u938SceilsVc5AB5Akwqlo2HB", 'SECRET_KEY')
即使我提供的令牌是错误的,也得到此响应:
[{“ sss” =>“ 333”},{“ alg” =>“ HS256”}]
实际上,对于所有字符,直到'D',我都得到相同的响应
如果我使用F
和上面的其他代码,则会显示预期的错误:
JWT.decode("eyJhbGciOiJIUzI1NiJ9.eyJzc3MiOiIzMzMifQ.CwX_1FztYHVpyx_G27u938SceilsVc5AB5Akwqlo2HF", 'SECRET_KEY')
JWT :: VerificationError(引发签名验证) 来自(irb):34
这可能是什么原因?是预期的行为还是我在这里做错了什么?
答案 0 :(得分:1)
原因是base64url编码。 JWT的三个部分都是base64url编码的。 Base64 encoding将输入数据转换为6位表示形式,并映射到一组64个ASCII字符。如果您有3个字节的源数据,则base64编码结果的长度为4个字符,每个字符代表6位值,因此4 * 6位= 24位。
在您的情况下,编码的签名具有43个字符,这意味着43 * 6 = 258位。 因此,从理论上讲,您可以编码258位,但是签名只有256位(32字节)长,这意味着最后有2个无关紧要的位。
通过查看base64 encoding table可以看出,“ A”至“ D”代表6位值0(000000)至4(000011),因此前四个仍然有效的位都相同,只有最后两个无关紧要的位在变化。但是字符“ E”代表5(000100),它将更改256位值的最后一位。
结论:一切都很好,这里没有错,可以按预期工作。