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 实战干货 中所涉及到的 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 相关学习进行了铺垫。