基于JJWT理解JWT,JWS,JWE

JWT , 全写JSON Web Token, 是开放的行业标准RFC7591,用来实现端到端安全验证.
从开发者理解的角度来说:

  • JWT 是一个定义传递信息的标准
  • JWT 的Token是一个Base64编码的字符串, 类似
eyJhbGciOiJIUzI1NyJ9.eyJzdWIiOiJvc2NhciJ9.p1no61S/XIQ0QNEhzB8e0eI9Q39jIGgkDxUjYipKnzw=

这个字符串里面包含2个点号(.),可以分成3段, 分别表示头部,负载和签名。

关于JWT的更多介绍,可以参考:
JWT介绍以及java-jwt的使用

JWT Token是如何产生的

  1. 最简单的JWT由两部分组成: header(头部) 和 payload(负载)
    关于JWT的基本介绍, 可以参考:
    JWT介绍以及java-jwt的使用

比如头部是:

{
  "alg": "none"
}

负载是:

Hello, JWT
  1. 移除不必要的空格
		String header = "{\"alg\":\"none\"}";
		String payload= "Hello, JWT";
  1. 获取UTF-8的字节后,使用Base64进行编码
		String encodedHeader = Base64.getEncoder().encodeToString(header.getBytes());
		String encodedPayload = Base64.getEncoder().encodeToString(payload.getBytes());

4.将编码后的字符使用点号(.) 连接起来

String compact= encodedHeader + "." + encodedPayload + ".";

连接后的Token如下:

eyJhbGciOiJub25lIn0=.SGVsbG/vvIwgSldU.

从这里可以看出, JWT其实并不神秘, 只是对字符串进行了Base64编码, 所以通过解码或是一些在线的Base64解码的工具就可以直接得到结果了,比如 https://base64.us/
在这里插入图片描述

因为没有进行数字签名,上面的Token是不安全和未受保护的, 不能保证没有第三方对这个内容进行修改,所以为了提升安全,就需要添加数字签名。

JWS ,signedJWT -加密签名的JWT

上面的示例payload是一个字符串, 但实际使用时,payload更多是JSON 格式的数据, 对JWT进行数字签名后的Token 就称为JWS了。

还是从简单的示例来看:

  1. 头部
{
  "alg": "HS256"
}

使用HS256算法进行数字签名
2. 负载

{
"sub":"oscar"
}
  1. 去除空格的内容
		String header = "{\"alg\":\"HS257\"}";
		String payload=  "{\"sub\":\"oscar\"}";
  1. 获取字节数组和使用Base64编码,并且使用点号连接
		String encodedHeader = Base64.getEncoder().encodeToString(header.getBytes());
		String encodedPayload = Base64.getEncoder().encodeToString(payload.getBytes());
		String concatenated = encodedHeader + '.' + encodedPayload;
  1. 使用足够安全的摘要加密算法(比如使用HMAC-SHA-256), 获取加密后的摘要,也就是数字签名。最后将头部、负载和签名组合起来就是一个完整的Token 了。
		String header = "{\"alg\":\"HS257\"}";
		String payload=  "{\"sub\":\"oscar\"}";
		Key secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
		String encodedHeader = Base64.getEncoder().encodeToString(header.getBytes());
		String encodedPayload = Base64.getEncoder().encodeToString(payload.getBytes());
		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 ); //将签名和头,载荷连接起来
        System.out.println(compact);

由此产生的Token如下:

eyJhbGciOiJIUzI1NyJ9.eyJzdWIiOiJvc2NhciJ9.HjomJsGXx3vO/x16euJo7kFsBFJaOEdyoj5Czbt3XE4=

JWE,  encrypted JWT

JWE就是对数字签名的Token进行加密,加密之后使用Base64解码之后是无法直接获取Token的内容的, 加密的方式可以是对称加密, 可以是非对称加密。JJWT也提供了一些加密的快速方法, 但是在不同的版本中支持有差异, 这里使用Java 本身的DES对称加密进行演示。
示例代码如下:

	
	@Test
	public void jwe() throws Exception {
		String header = "{\"alg\":\"HS257\"}";
		String payload = "{\"sub\":\"oscar\"}";
		Key secretKey = Keys.secretKeyFor(SignatureAlgorithm.HS256);
		String encodedHeader = Base64.getEncoder().encodeToString(header.getBytes());
		String encodedPayload = Base64.getEncoder().encodeToString(payload.getBytes());
		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);
		
		//使用DES算法对称加密
		String strKey = "this is my password";
		DESKeySpec desKeySpec = new DESKeySpec(strKey.getBytes(StandardCharsets.UTF_8));
		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey key = keyFactory.generateSecret(desKeySpec);

		Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		cipher.init(Cipher.ENCRYPT_MODE, key);

		byte[] encryptedBytes = cipher.doFinal(compact.getBytes(StandardCharsets.UTF_8));
		String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);
		System.out.println(encryptedText);
		
	}

加密之后的Token使用Base64解码后得到的内容如下:
在这里插入图片描述

要得到正确的内容, 需要使用密钥进行解密之后, 再进行Base64解码。

关于Java对称加密与解密, 可以参考:
Java实现对称加密(DES,AES)快速入门示例

名词解释

  • JWT, JSON Web Token。 JSON格式的Web令牌
  • JWS: signed JWT,签名的JWT
  • JWE: encrypted JWT,签名且加密的JWT(对负载也加密)

三者的关系如下:
在这里插入图片描述

完整示例代码

  • https://github.com/osxm/java-ency/blob/master/src/main/java/com/osxm/je/topic/security/JjwtDemo.java


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/84722.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ARM开发(cortex-A7核,UART总线实验)

1.目标:键盘输入一个字符a,串口工具显示b; 键盘输入一个字符串"nihao",串口工具显示"nihao"; 2.框图分析: 3.代码: ---.h头文件--- #ifndef __UART4_H__ #define __UART4_H__#include "st…

关于ubuntu下面安装cuda不对应版本的pyTorch

最近换了台新的linux的ubuntu的服务器,发现其实际安装的cuda版本为11.4,但是pytorch官方给出的针对cuda 11.4并没有具体的pytorch的安装指令,于是采用不指定pytorch版本直接安装让其自动搜索得到即可 直接通过: pip3 install tor…

卷积神经网络——上篇【深度学习】【PyTorch】【d2l】

文章目录 5、卷积神经网络5.1、卷积5.1.1、理论部分5.1.2、代码实现5.1.3、边缘检测 5.2、填充和步幅5.2.1、理论部分5.2.2、代码实现 5.3、多输入多输出通道5.3.1、理论部分5.3.2、代码实现 5.4、池化层 | 汇聚层5.4.1、理论部分5.4.2、代码实现 5、卷积神经网络 5.1、卷积 …

Redis系列(四):哨兵机制详解

首发博客地址 https://blog.zysicyj.top/ 前面我们说过,redis采用了读写分离的方式实现高可靠。后面我们说了,为了防止主节点压力过大,优化成了主-从-从模式 思考一个问题,主节点此时挂了怎么办 这里主从模式下涉及到的几个问题&a…

thinkphp6.0 配合shell 脚本 定时任务

1. 执行命令&#xff0c;生成自定义命令 php think make:command Custom<?php declare (strict_types 1);namespace app\command;use app\facade\AdmUser; use think\console\Command; use think\console\Input; use think\console\input\Argument; use think\console\i…

操作系统-笔记-第四章-文件管理

目录 四、第四章——文件管理 1、文件管理——基础概念 &#xff08;1&#xff09;文件结构 &#xff08;2&#xff09;操作系统提供的接口 &#xff08;3&#xff09;总结 2、文件的逻辑结构 &#xff08;1&#xff09;有结构文件&#xff08;类似SQL表文件&#xff09…

无涯教程-PHP - preg_match()函数

preg_match() - 语法 int preg_match (string pattern, string string [, array pattern_array], [, int $flags [, int $offset]]]); preg_match()函数在字符串中搜索pattern&#xff0c;如果存在pattern&#xff0c;则返回true&#xff0c;否则返回false。 如果提供了可选…

Pandas学习(完成文件写入、追加写入、读取操作)

问题引入 现在有这么一个需求 我要对我的很多设备进行快照处理&#xff0c;打完快照之后需要记录我的设备IP和快照时间 当我们解决了需求的其他内容&#xff0c;只剩记录信息的时候&#xff0c;可以怎么做呢 这时候就可以引入我们的pandas模块啦&#xff0c;它对数据进行一系列…

Java【HTTP】什么是 Cookie 和 Session? 如何理解这两种机制的区别和作用?

文章目录 前言一、Cookie1, 什么是 Cookie2, Cookie 从哪里来3, Cookie 到哪里去4, Cookie 有什么用 二、Session1, 什么是 Session2, 理解 Session 三、Cookie 和 Session 的区别总结 前言 各位读者好, 我是小陈, 这是我的个人主页, 希望我的专栏能够帮助到你: &#x1f4d5; …

开源在线图片设计器,支持PSD解析、AI抠图等,基于Puppeteer生成图片

Github 开源地址: palxiao/poster-design 项目速览 git clone https://github.com/palxiao/poster-design.git cd poster-design npm run prepared # 快捷安装依赖指令 npm run serve # 本地运行将同时运行前端界面与图片生成服务(3000与7001端口)&#xff0c;合成图片时…

【C语言学习】指针变量

一、运算符& 1.&运算符可以获得变量的地址&#xff0c;它的操作数必须是变量 int i; printf("%x",&i);2.地址的大小是否与int相同取决于编译器 int i; printf("%p",&i);//%p以32进制输出i的地址二、指针变量 指针变量是保存地址的变量…

JavaWeb+JSP+SQL server学生学籍管理系统设计与实现(源代码+论文+开题报告+外文翻译+答辩PPT)

需求分析 本系统主要是针对各个高校的学生学籍进行管理&#xff0c;系统满足以下几点要求&#xff1a; 系统安全性。由于此系统中的操作都是由用户操作的&#xff0c;所以对于用户的权限设置比较严格。对于数据库&#xff0c;设置了不同用户的权限&#xff0c;不同权限进入不…

【并发编程】详解并发编程中Synchronized的特性(可见性、有序性、可重入性、禁止指令重排序)(๑•̀ㅂ•́)و✧

1、synchronized 禁止指令重排分析 我们先看如下代码&#xff1a; class MonitorExample {int a 0;public synchronized void writer() { //1a; //2} //3public synchronized void reader() { //4int i …

[虚幻引擎] UE使用虚拟纹理在模型上显示挖空效果

此教程是记录如在UE中使用虚拟纹理&#xff0c;实现模型挖洞的效果。 1. 新建项目&#xff0c;开启项目支持虚拟纹理并并重启。 2. 新建一个基础关卡 3. 拖动“运行时虚拟纹理体积” 进入场景&#xff0c;并把体积修改变大&#xff0c;以可以完全包括到地板。 4. 创建一个虚拟纹…

记一次从Redis弱口令到RCE

Fscan扫描网段发现了一些开启了6379的服务器&#xff0c;逐个尝试了下未授权&#xff0c;然后尝试了下爆破 hydra爆破redis hydra -P [字典目录] redis://xxx.xxx.xxx.xxx结果还真让爆出来一个 得到密码后&#xff0c;连接上去&#xff0c;这里用的是Another Redis Desktop M…

FastDFS与Nginx结合搭建文件服务器,并实现公网访问【内网穿透】

文章目录 前言1. 本地搭建FastDFS文件系统1.1 环境安装1.2 安装libfastcommon1.3 安装FastDFS1.4 配置Tracker1.5 配置Storage1.6 测试上传下载1.7 与Nginx整合1.8 安装Nginx1.9 配置Nginx 2. 局域网测试访问FastDFS3. 安装cpolar内网穿透4. 配置公网访问地址5. 固定公网地址5.…

【嵌入式】MKV31F512VLL12 微控制器 (MCU) 、Cyclone® IV E EP4CE10E22I8LN,FPGA-现场可编程门阵列芯片

1、MKV31F512VLL12 微控制器 (MCU) 是适用于BLDC、PMSM和ACIM电机控制应用的高性能解决方案。这些MCU采用运行频率为100MHz/120MHz、带数字信号处理 (DSP) 和浮点单元 (FPU) 的ARM Cortex-M4内核。KV3x MCU配备两个采样率高达1.2MS/s的16位ADC、多个控制定时器以及512KB闪存。 …

Vue使用Element的表格Table显示树形数据,多选框全选无法选中全部节点

使用Element的组件Table表格&#xff0c;当使用树形数据再配合上多选框&#xff0c;如下&#xff1a; 会出现一种问题&#xff0c;点击左上方全选&#xff0c;只能够选中一级树节点&#xff0c;子节点无法被选中&#xff0c;如图所示&#xff1a; 想要实现点击全选就选中所有的…

【HarmonyOS】服务卡片 API6 JSUI跳转不同页面

【引言】 “JS卡片支持为组件设置action&#xff0c;包括router事件和message事件&#xff0c;其中router事件用于应用跳。若设置router事件&#xff0c;则action属性值为"router"&#xff1b;abilityName为卡片提供方应用的跳转目标Ability名&#xff1b;params中的…

stm32的命令规则

stm32型号的说明&#xff1a;以STM32F103RBT6这个型号的芯片为例&#xff0c;该型号的组成为7个部分&#xff0c;其命名规则如下&#xff1a;