• JWT一篇通


    JWT 是什么?

    JWT(JSON Web Token)是一种开放的标准,标准的编号是RFC7591。用于在不同实体之间安全地传输信息。它是基于 JSON 编码的令牌。

    JWT 的组成

    JWT由三个部分组成:头部(Header)、载荷(Payload)和签名(Signature)。

    1. 头部(Header)包含了令牌的类型(typ)和所使用的签名算法(alg),通常使用 Base64 编码表示。示例如下:
    {
      "alg": "HS256",
      "typ": "JWT"
    }
    
    • 1
    • 2
    • 3
    • 4
    1. 载荷(Payload)是令牌的主要信息存储部分,包含了各种声明(claims),用于表示关于实体(用户、设备或其他主体)和其他补充数据的信息。载荷可以包含标准声明(例如:iss,sub,exp,nbf,iat,aud 等),也可以包含自定义声明。载荷同样会被进行 Base64 编码表示,并传输在令牌中。示例如下:
    {
      "sub": "myapp",
      "name": "oscar",
      "role": "admin"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    1. 签名(Signature)是使用密钥对头部和载荷进行签名的哈希值,以确保令牌不会被篡改。签名通常使用头部中指定的算法(例如:HMAC、RSA 等)和密钥来生成,并以字符串形式附加在令牌的末尾。签名验证可以用于验证令牌的完整性和真实性。

    Java语言产生JWT的过程来看,步骤如下:

    1. 产生头部的Base64编码串
    String header = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
    String encodedHeader = Base64.getEncoder().encodeToString(header.getBytes());
    
    • 1
    • 2
    1. 产生载体的Base64编码串
    		String payload = "{\"sub\":\"myapp\",\"name\":\"oscar\"}";
    		String encodedPayload = Base64.getEncoder().encodeToString(payload.getBytes());
    
    • 1
    • 2
    1. 使用点号. 连接头部和载体之后, 再使用签名算法进行签名, 将签名后的内容附加在整个字符串的后面
    		Key secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
    		String concatenated = encodedHeader + '.' + encodedPayload;
    
    		Mac sha256_HMAC = Mac.getInstance("HmacSHA256");
    		sha256_HMAC.init(secretKey);
    		byte[] signature = sha256_HMAC.doFinal(concatenated.getBytes("utf-8"));
    		String compact = concatenated + '.' + Base64.getEncoder().encodeToString(signature);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    产生后得到的完整字符串如下:

    eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJteWFwcCIsIm5hbWUiOiJvc2NhciJ9.5z6NoiF7MR999wOPn2NU6HnyPODx66qm5yRT+n8pNHs=
    
    • 1

    通过 https://base64.us/ 解码之后获取的内容如下图:
    在这里插入图片描述

    从上面可以看出, JWT的令牌就是一串字符串。

    JWT 的作用

    JWT 适用于在网络请求中传输身份验证和授权信息,常用于构建无状态(stateless)的身份验证和访问控制机制。客户端在接收到令牌后,可以通过对令牌进行解码和验证来验证其有效性,并使用其中的信息进行授权和身份验证。

    总结起来,JWT 是一种使用 JSON 编码的安全令牌,由头部、载荷和签名部分组成,可用于在实体之间传递信息和验证身份。它提供了一种简单、可扩展和自包含的机制,用于处理身份验证和授权相关的任务。
    JWT也经常用于单点登录, 就是用户登录A系统之后,产生一个令牌, 之后访问其他系统都带上这个 Token,进而可以访问B,C,D等系统。

    JWT优缺点

    1. 基于JSON,方便解析
    2. 可以在令牌中定义丰富的内容,易于扩展
    3. 通过非对称加密和数字签名,防篡改,安全性高
    4. 资源服务使用JWT就可以完成授权,不需要依赖授权服务器

    缺点:

    • JWT令牌较长, 占用较多的存储空间。

    JWT的加密解密

    JWT 的加密和解密通常涉及到以下三个步骤:

    1. 创建 JWT:
      创建 JWT 需要准备三个部分:头部(Header)、载荷(Payload)和签名(Signature)。在创建 JWT 时,首先将头部和载荷进行 Base64 编码,并将这两个编码后的字符串用点号连接起来形成 JWT 的第一部分。接着,使用密钥和指定的签名算法对前面的字符串进行签名,生成签名字符串,并与前面的字符串用点号连接起来形成 JWT 的最终形式。

    2. 验证 JWT:
      验证 JWT 的过程通常包括以下几个步骤:首先,对 JWT 中的头部和载荷部分进行Base64解码,提取其所包含的信息。接下来,用与创建 JWT 相同的算法和密钥,对头部和载荷部分计算签名。最后,将计算得出的签名字符串与 JWT 中的签名部分进行比较。如果两者相等,则表明 JWT 未被篡改过,可以被信任。

    3. 解码 JWT:
      如果需要查看 JWT 中包含的数据,可以对 JWT 的第一部分进行 Base64 解码,以得到头部和载荷的信息。解码后的结果通常为 JSON 格式的字符串,可以通过相应的 JSON 解析库将其转换为对象。

    需要注意的是,JWT 中的头部和载荷信息并没有加密,只进行了 Base64 编码。因此,这些信息可以被轻易地获取。为了保护数据的机密性,通常会使用加密算法加密载荷部分,即将其转换为 JWE(JSON Web Encryption)格式。JWE 提供了一种标准化的加密方式,以保护 JWT 中的敏感信息。加密 JWE 包括头部、密钥和加密后的密文等部分,需要使用相应的算法和密钥来进行解密。

    总的来说,JWT 的加密和解密通常包括创建 JWT、验证 JWT 和解码 JWT 等步骤。其中,验证 JWT 可以用于验证 JWT 是否被篡改过,以保证 JWT 的完整性和可信度。而将载荷部分加密则可以保护 JWT 中的敏感信息,提高 JWT 的机密性。



  • 相关阅读:
    MySQL 中的 INSERT 是怎么加锁的?(荣耀典藏版)
    MindSpore梯度进阶操作
    Redis-列表
    2173. 最多连胜的次数
    应用没“积分”,系统就不让运行?Android 13部分功能曝光
    flutter项目引入本地静态图片资源并展示
    Mac系列之:Mac安装tesseract和python使用pytesseract、pillow包提取图片中中文
    【论文精读3】MVSNet系列论文详解-P-MVSNet
    mysql中 COALESCE和CASE WHEN的使用以及创建或替换视图
    Kubernates 1.24.3 操作
  • 原文地址:https://blog.csdn.net/oscar999/article/details/132706309