【问题标题】:JWT token decoding even when the last character of the signature is changed即使更改签名的最后一个字符,也可以进行 JWT 令牌解码
【发布时间】:2021-06-02 20:05:45
【问题描述】:

我只是在一个 rails 应用程序上尝试 JWT 令牌,使用这个 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

这可能是什么原因?这是预期的行为还是我在这里做错了什么?

【问题讨论】:

    标签: ruby-on-rails jwt base64 digital-signature


    【解决方案1】:

    原因是base64url编码。 JWT 的三个部分都是 base64url 编码的。 Base64 encoding 将输入数据转换为 6 位表示,映射到一组 64 个 ASCII 字符。如果您有 3 个字节的源数据(24 位),则 base64 编码结果为 4 个字符长,每个字符代表一个 6 位值,因此 4 * 6 位 = 24 位。如果需要编码的位数不能被6整除而没有余数,就会多出一个字符2或4个无意义的位。

    在您的情况下,编码签名有 43 个字符,这意味着 43 * 6 = 258 位。 所以理论上你可以编码 258 位,但签名只有 256 位(32 字节)长,这意味着最后有 2 个无关紧要的位。

    查看base64 encoding table 显示,“A”到“D”代表 6 位值 0 (000000) 到 4 (000011),因此前四位仍然有效,它们都是相同的,并且只有最后两个无关紧要的位正在改变。但是字符 'E' 代表 5 (000100) 并且会改变 256 位值的最后一位。

    下表说明了这一点。它显示了签名的最后 4 个 base64 字符,包括最后一个字符(A-D)的可能变化以及原始数据的位和字节数: 该范围内最后一个字符的变化只会导致最后两位(浅灰色)发生变化,但不会改变原始数据,因为变化的位超出了原始数据的最后一位。

    如果你真的很在意最后的2位,可以考虑把签名算法改成HS384。

    然后你就有了一个 384 位(= 48 字节)的散列,它用 64 个 Base64 字符表示。 384可以被8整除,也可以被6整除,所以最后没有不重要的位,最后一个字符的任何变化都会导致验证失败。

    HS512 会出现与 HS256 相同的“问题”,甚至最后还有 4 个无关紧要的位,但更长的哈希值(512 位 vs. 384 位 vs. 256 位)被认为更安全。

    结论:一切都很好,这里没有错。签名的验证基于其二进制值,不受编码特性的影响。如果你担心的话,你可以改变算法,但我认为这并不是真正必要的,算法的选择不应该以此为基础。

    【讨论】:

    • 感谢您的解释。认为这是一个错误。
    猜你喜欢
    • 2020-02-17
    • 2020-11-14
    • 2021-06-21
    • 2017-05-14
    • 2020-09-24
    • 2018-09-30
    • 2021-04-11
    • 2014-12-13
    • 2018-06-20
    相关资源
    最近更新 更多