如何使用 JJWT 和 jose4j 生成符合标准的 JWE(加密 JWT)

秋瑶同学_7009

秋瑶同学_7009

2026-08-06

775人浏览

原创

如何使用 JJWT 和 jose4j 生成符合标准的 JWE(加密 JWT)

jjwt 官方库(0.11.x/0.12.x)不原生支持 jwe 加密,encryptwith() 方法并不存在于其 jwtbuilder 中;需借助 jose4j 等兼容 jose 标准的库完成 jwe 构建与加密。本文详解替代方案及完整实现步骤。

jjwt 官方库(0.11.x/0.12.x)不原生支持 jwe 加密,encryptwith() 方法并不存在于其 jwtbuilder 中;需借助 jose4j 等兼容 jose 标准的库完成 jwe 构建与加密。本文详解替代方案及完整实现步骤。

在 Java 生态中,尽管 JJWT 是最广为人知的 JWT 库,但需明确一个关键事实:截至 v0.12.3(当前最新稳定版),JJWT 仅完整支持 JWS(签名 JWT)和 JWA(签名算法),并不提供 JWE(加密 JWT)的构建能力。官方文档中提及的 encryptWith() 方法属于早期规划或社区误传,并未实现在任何公开发布的版本中(包括你使用的 0.11.5 或升级后的 0.12.3)。因此,直接依赖 JJWT 实现 JWE 是不可行的。

✅ 正确路径是采用 JOSE 标准兼容库,如 jose4j —— 它完整实现了 RFC 7516(JWE)、RFC 7515(JWS)和 RFC 7518(JWA),且与 JJWT 无缝协作:先用 JJWT 生成标准 JWS(即明文 JWT),再用 jose4j 将其整体作为 payload 进行加密封装为 JWE。

以下是可直接运行的完整示例(基于 JDK 8+):

✅ 1. 添加必要依赖(Gradle)

// JJWT 用于生成原始 JWT(JWS)
implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3'

// jose4j 用于 JWE 加密(必需)
implementation 'org.bitbucket.b_c:jose4j:0.9.4'

⚠️ 注意:jose4j:0.9.4 是目前最稳定、广泛验证的版本,兼容 JDK 8–17;避免使用较新快照版以防 API 变更。

✅ 2. 生成 JWS(明文 JWT),再加密为 JWE

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import org.jose4j.jwe.ContentEncryptionAlgorithmIdentifiers;
import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers;
import org.jose4j.lang.JoseException;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Map;

public class JweGenerator {

    private static final String ENCRYPTION_SECRET = "ThisIsASecretKey1234567890123456"; // 必须为 32 字节(AES-256)

    public static String generateEncryptedJwt(Map<string object> claims, String jwtIssuer,
                                              long accessTokenExpiryMin, ZonedDateTime currentTime) throws JoseException {
        // Step 1: 使用 JJWT 构建并签名原始 JWT(JWS)
        String jwsToken = Jwts.builder()
                .setClaims(claims)
                .setIssuer(jwtIssuer)
                .setIssuedAt(Date.from(currentTime.toInstant()))
                .setExpiration(Date.from(currentTime.plusMinutes(accessTokenExpiryMin).toInstant()))
                .signWith(getSigningKey()) // 替换为你自己的 SigningKey(如 HMAC-SHA256 或 RSA 私钥)
                .compact();

        // Step 2: 使用 jose4j 将 JWS 作为 payload 加密为 JWE
        SecretKey key = Keys.hmacShaKeyFor(ENCRYPTION_SECRET.getBytes(StandardCharsets.UTF_8));
        JsonWebEncryption jwe = new JsonWebEncryption();
        jwe.setPayload(jwsToken); // JWS token 作为 JWE 的 payload
        jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.A256KW); // 密钥加密算法:AES-256-KeyWrap
        jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_256_CBC_HMAC_SHA_512); // 内容加密算法
        jwe.setKey(key);

        return jwe.getCompactSerialization(); // 返回标准 JWE Compact Serialization(形如 a.b.c.d.e)
    }

    private static SecretKey getSigningKey() {
        // 示例:HMAC-SHA256 签名密钥(生产环境建议使用 RSA/ECDSA)
        String signingSecret = "your-signing-secret";
        return Keys.hmacShaKeyFor(signingSecret.getBytes(StandardCharsets.UTF_8));
    }
}</string>

? 关键说明与注意事项

  • 密钥长度严格要求:A256KW 要求对称密钥为 32 字节(256 bit)。若字符串不足,需补位或使用 Keys.hmacShaKeyFor(...) 自动生成合规密钥;切勿硬编码弱密钥。
  • 算法组合兼容性:A256KW + A256CBC-HS512 是 JOSE 推荐的强加密组合,确保接收方(如 Spring Security OAuth2 Resource Server)支持该算法集。
  • JWE 结构清晰:生成的 JWE 是五段 Base64Url 编码字符串(a.b.c.d.e),分别对应:Protected Headers、Encrypted Key、Initialization Vector、Ciphertext、Authentication Tag。
  • 解密方必须匹配:消费端需使用相同密钥和算法解密 JWE,再解析内部的 JWS 并验证签名——这是“签名+加密”双重安全模型的核心。

✅ 总结

JJWT 不是万能 JWT 工具箱,而是专注 JWS/JWA 的轻量级实现。当业务需要 JWE 时,应理性选择专业 JOSE 库(如 jose4j)协同工作。本方案兼顾安全性、标准兼容性与工程落地性,已广泛应用于微服务鉴权、跨域 Token 传输等高安全场景。务必对密钥进行安全存储(如 HashiCorp Vault、KMS),并定期轮换。

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

9477

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

6642

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

5892

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

1044

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

868

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1236

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2489

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

19831

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

1135

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
phpStudy极速入门视频教程
phpStudy极速入门视频教程

共6课时 | 54.6万人学习

独孤九贱(4)_PHP视频教程
独孤九贱(4)_PHP视频教程

共89课时 | 133.4万人学习