基于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对称加密进行演示。
示例代码如下:

	@Testpublic 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


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Python进阶] 类的设计模式

4.11 设计模式 在Python中,类的设计模式是指一种通用的解决方案或设计模板,针对特定的问题或需求构建类结构,并提供相关的方法和属性。这些设计模式可以帮助开发人员遵循最佳实践、提高代码质量、增强可读性、降低维护成本。 需要注意的是&a…

房屋结构健康监测,科技助力让建筑更安全

房屋建筑是人们赖以生存的场所,然而当前我国许多房屋已经达到了使用寿命的中期,房屋的安全系数逐年降低,风险也随着时间的推移而累积。长期以来,我国的房屋普遍存在寿命短、隐患多的问题,“重建设,轻管理”…

探索PDF校对:为何这是现代数字文档的关键步骤

在今日的数字化浪潮中,文档的创建与分享从未如此频繁。尤其是PDF,作为一个普遍接受的标准文件格式,其在企业、学术和日常生活中的应用已经无处不在。但随之而来的挑战是如何确保文档的准确性和专业性。让我们深入探索PDF校对的重要性以及它为…

[国产MCU]-W801开发实例-定时器

定时器 文章目录 定时器1、定时器介绍2、定时器驱动API3、定时器使用示例本文将详细介绍如何使用W801的定时器模块。 1、定时器介绍 W801的定时器包含一个32-bit自动加载的计数器,该计数器由系统时钟经过分频后驱动。 W801有 6路完全独立定时器。实现了精确的定时时间以及中断…

element-ui中的el-table的summary-method(合计)的使用

场景图片: 图片1: 图片2: 一:使用element中的方法 优点: 直接使用summary-method方法,直接,方便 缺点: 只是在表格下面添加了一行,如果想有多行就不行了 1:h…

一、MQ的基本概念

1、初识MQ MQ全称是Message Queue,消息队列,多用于系统之间进行异步通信。队列的概念数据结构中有详细介绍过,先进先出,消息队列就是存储消息的数据结构。 同步调用和异步调用两者之间的区别: 同步调用:发…

opencv-dnn

# utils_words.txt 标签文件 import osimage_types (".jpg", ".jpeg", ".png", ".bmp", ".tif", ".tiff")def list_images(basePath, containsNone):# return the set of files that are validreturn list_file…

gdb 条件断点

条件断点,顾名思义就是有条件才会触发的断点,一般设置此类断点形如:b xxx if xxx,如: 要触发此断点则需要 is_created 0。打完断点我们也可以用 info b 查看一下当前已经设置的断点信息,如: 断…

【JavaSE】接口

文章目录 接口的概念接口的使用接口的特性实现多个接口接口间的继承抽象类和接口的区别 接口的概念 接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。在Java中,接口可以看成是:多个类的公共规…

Spring核心配置步骤-完全基于XML的配置

Spring框架的核心配置涉及多个方面,包括依赖注入(DI)、面向切面编程(AOP)等。以下是一般情况下配置Spring应用程序的核心步骤: 1. **引入Spring依赖:** 在项目的构建工具(如Maven、…

23 WEB漏洞-文件上传之解析漏洞编辑器安全

目录 几种中间件解析漏洞简要演示几种常见WEB编辑器简要演示几种常见CMS文件上传简要演示贴近实际应用下的以上知识点演示 各个WEB编辑器安全讲解 https://navisec.it/编辑器漏洞手册/ 各个CMS文件上传简要讲解 wordpress,phpcms, 几种中间件解析漏洞简…

JDK 新版本中都有哪些新特性?

面试回答 JDK 8 推出了 Lambda 表达式、Stream、Optional、新的日期 API 等 JDK 9 中推出了模块化 JDK 10 中推出了本地变量类型推断 JDK 12 中增加了 switch 表达式 JDK 13 中增加了 text block JDK 14 中增加了 Records JDK 15 中增加了封闭类 JDK 17 中扩展了 switch…

探索未知世界:桌面端3D GIS引领地理信息新时代

近年来,桌面端的三维地理信息系统(3D GIS)在地理信息领域迎来了显著的发展,为我们带来了更深入、更丰富的地理空间认知和数据分析体验。从城市规划到环境保护,从资源管理到应急响应,桌面端的3D GIS正逐渐成…

Mysql定时备份事件

创建了一个名为backup_database的定时任务,每天自动在当前时间的后一天开始执行。备份数据库的代码使用mysqldump命令将数据库导出为sql文件保存在指定的备份目录中。 需要注意的是,上述代码中的用户名 (username)、密码 (password)、主机名 (hostname) …

Java程序设计——在一个给定的字符串中查找并解析姓名、出生日期、个人网站、身高和体重信息,并输出相应的结果

package ch4;public class FindMess {public static void main(String[] args) {String mess "姓名:张三 出生时间:1989.10.16。个人网站:http://www.zhang.com。身高:185 cm,体重:72 kg";int index (int)(mess.indexOf(":")); //mess调用indexOf(Stri…

如何解决跨域问题

跨域问题是指在浏览器中发起跨域请求时,由于浏览器的同源策略限制,导致请求被拒绝或无法正常发送和接收数据。同源策略要求两个页面具有相同的协议、域名和端口号,否则就会出现跨域问题。 为了解决跨域问题,可以采取以下方法之一…

git Update failed cannot lock ref

报错详情 解决方案 百度了很多方案,过滤出了有效方案 去该项目下的.git文件里找到报错文件,本例中即为:.git/refs/tags/pre-RELEASE-PRE-20230817-03 删除该文件,重新pull,pull成功问题解决

Java并发工具类

JDK并发包中常用并发工具类: CountDownLatch、CyclicBarrier和Semaphore工具类提供了一种并发流程控制的手段; Exchanger工具类则提供了在线程间交换数据的一种手段。 等待多线程完成的CountDownLatch CountDownLatch允许一个或多个线程等待其他线程完成…

Electron学习3 使用serialport操作串口

Electron学习3 使用serialport操作串口 一、准备工作二、 SerialPort 介绍1. 核心软件包(1) serialport(2) serialport/stream(3) serialport/bindings-cpp(4) serialport/binding-mock(5) serialport/bindings-interface 2. 解析器包3. 命令行工具 三、创建一个demo程序1. 创建…

NOI2015D. 荷马史诗

荷马史诗 题目描述 追逐影子的人,自己就是影子。 ——荷马 Allison 最近迷上了文学。她喜欢在一个慵懒的午后,细细地品上一杯卡布奇诺,静静地阅读她爱不释手的《荷马史诗》。但是由《奥德赛》和《伊利亚特》组成的鸿篇巨制《荷马史诗》实在是…