【JWT在线解密为什么不用提供密钥也可以】

无密钥解码token令牌的header和payload

  • 这为什么
  • JWT解释
  • 上代码
    • 本次使用的token
    • 代码复现
    • 尾解析报错是为啥
    • token的安全保证(如何验证)

这为什么

不知道大家在接触JWT的token后有没有想过为什么我用了各种加密方式加密后的token在不告诉在线解密工具密钥的时候他就能解密出来我token里面的信息。而且大多数解密工具在解密时也不需要我们提供密钥。

JWT解释

百度一下你就知道 JWT 时JSON WEB TOKEN ,也就是说是一个json令牌
JWT(JSON Web Token)是一种用于双方之间传递安全信息的简洁的、URL安全的表述性声明规范。它由三个部分组成:头部,载荷和签名。

  1. 头: 头部包含了令牌的类型和加密算法的信息。
  2. 体: 载荷是存放有效信息的地方。它可以包含用户的相关信息,例如用户的ID、用户名等。
  3. 尾: 签名是用来验证令牌的完整性的。它是头部和载荷的结合,通过指定的秘钥进行加密生成的。

上代码

本次使用的token

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6ImFkbWluIiwidWlkIjoiMmIyMmJjNjUtZGU5YS00ZGRlLWJjZDctNjMyNWQ0NWViNWQxIiwibG9naW5UaW1lIjoxNjcyNzM5NDk4MjEyLCJleHBpcmVUaW1lIjoxNjcyNzM5Nzk4MjEyfQ.8wrNGKSCrdUg_sz8JyVgsxpHigFJ9pk_gs4rwc5T5v4

在线解析后的结果是
【JWT在线解密为什么不用提供密钥也可以】_第1张图片

代码复现

【JWT在线解密为什么不用提供密钥也可以】_第2张图片
从上面图中的代码可以看出,我在不借助密钥的情况下,仅使用base64就已经获得的 这里基本上可以猜测出在线解析JWT的大致逻辑了,但为什么在解析的时候报错了。

尾解析报错是为啥

明明三段的编码都是base64,但前两段成功了,最后一段报错。

这是因为在JWT的生成时的规则不是三段都是一样的base64。
JWT在生成token的时候是会先将进行普通的base64然后再用这两个已经编码过的字符串去生成签名。但签名后 (第三段不是token整体) 的字符串也是经过编码的。

至于不一样的base64编码其实是添加了一层url编码
可以冲sign的代码中看出
【JWT在线解密为什么不用提供密钥也可以】_第3张图片
在这里插入图片描述
【JWT在线解密为什么不用提供密钥也可以】_第4张图片
通过代码截图可以看出,默认传的tue导致是用的encodeUrlSafe,而不是encode所以导致我们解码时部分字符解不出来导致的。
所以当解码签名时应该使用下面代码


    public static void main(String[] args) {
        String token ="eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6ImFkbWluIiwidWlkIjoiMmIyMmJjNjUtZGU5YS00ZGRlLWJjZDctNjMyNWQ0NWViNWQxIiwibG9naW5UaW1lIjoxNjcyNzM5NDk4MjEyLCJleHBpcmVUaW1lIjoxNjcyNzM5Nzk4MjEyfQ.8wrNGKSCrdUg_sz8JyVgsxpHigFJ9pk_gs4rwc5T5v4";
        String[] split = token.split("\\.");
        System.out.println("头:"+ split[0]);
        System.out.println("体:"+ split[1]);
        System.out.println("尾:"+ split[2]);
        System.out.println("解密 base64");
        Decoder decoder = Base64.getDecoder();
        System.out.println("头:"+ new String(decoder.decode(split[0])));
        System.out.println("体:"+ new String(decoder.decode(split[1])));
        System.out.println("尾:"+ new String(Base64.getUrlDecoder().decode(split[2])));
    }

但结果是这样的
【JWT在线解密为什么不用提供密钥也可以】_第5张图片
到这里就知道为什么解码失败了把,那么还会有个问题就是,我的信息在不用密钥的时候都已经暴露了,那怎么确定信息的安全呢?

token的安全保证(如何验证)

Created with Raphaël 2.3.0 开始 截取token前两段 头 和 体 并签名获得新的签名 开始验证 比较新签名出来的字符串和传入的token的第三段? 结束 失败 yes no

你可能感兴趣的:(学习记录,json,java,开发语言)