你知道你对 JSON Web Token 的认识存在误解吗
1.前言
JSON Web Token (JWT) 其实目前已经广为软件开发者所熟知了,但是 JOSE (Javascript Object Signing and Encryption) 却鲜有人知道,我第一次知道它是在 Spring Security 的官方文档中,它改变了我对 JWT 的一些认识。目前国内能找到相关中文资料不是太多。所以我觉得有必要归纳一下。
2. JOSE 概述
JOSE 是一种旨在提供在各方之间安全传递声明(claims)的方法的规范集。我们常用的 JWT 就包含了允许客户端访问特定应用下特定资源的声明。JOSE 制定了一系列的规范来达到此目的。目前该规范还在不断的发展,我们常用的包含以下几个 RFC :
JWS(RFC 7515) -JSON Web 签名,描述生成和处理签名消息 JWE(RFC 7516) -JSON Web 加密,描述了保护和处理加密 消息 JWK(RFC 7517) -JSON Web 密钥,描述 Javascript 对象签名和加密中加密密钥的 格式和处理 JWA(RFC 7518) -JSON Web 算法,描述了 Javascript 对象签名和加密中使用的 加密 算法 JWT(RFC 7519) -JSON Web 令牌,描述以 JSON 编码并由 JWS 或 JWE 保护的声明的表示形式
3. 我们都看错了 JWT
看了对 JWT 的描述中提到 “令牌以 JWS 或者 JWE 声明表示”。莫非我之前的认知是错误的吗?找了一些官方的资料研究了一番后,确实我之前的认知是不够全面的。
官方定义:
JSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties
直译过来:JSON Web 令牌(JWT)是一种紧凑的 URL 安全方法,用于表示要在两方之间转移的声明。
也就是说我们通常说的 JWT 实际上是一个对声明进行 JOSE 处理方式的统称。我们之前用的应该叫 JWS(JSON Web Signature),是 JWT 的一种实现,除了 JWS , JWT 还有另一种实现 JWE(JSON Web Encryption) 。它们之间的关系应该是这样的:
4. 什么是 JWE
JWS 我们就不说了,就是通常我们所说的 JWT。包括之前我在 Spring Security 实战干货[1] 中所涉及到的 JWT 都是 JWS。我们来说一下 JWE 。JWS 仅仅是对声明(claims)作了签名,保证了其不被篡改,但是其 payload(中段负载) 信息是暴露的。也就是 JWS 仅仅能保证数据的完整性而不能保证数据不被泄露。所以我以前也说过它不适合传递敏感数据。JWE 的出现就是为了解决这个问题的。具体的可以看下图:
从上面可以看出 JWE 的生成非常繁琐,作为 Token 可能比较消耗资源和耗时。用作安全的数据传输途径应该不错。
5. Spring Security jose 相关
这里需要简单提一下 Spring Security 提供了 JOSE 有关的类库 spring-security-oauth2-jose
,你可以使用该类库来使用 JOSE 。如果 Java 开发者要在 Spring Security 安全框架中使用 OAuth2.0 ,这个类库也是需要研究一下的。
6. 总结
今天我们对 JOSE 这个相对陌生的概念进行了认识,对 JOSE 规范集中的几个重要的 RFC 进行了列举。对之前的局限性认识也进行了纠正。为我们后续的 OAuth2.0 相关学习进行了铺垫。
参考资料
Spring Security 实战干货: https://www.felord.cn/categories/spring-security/