【经验分享】JWE 详解:比 JWT 更安全的令牌技术
简单介绍
传统 JWT 的工作原理
JWT
(JSON Web Token) 是一种开放标准(RFC 7519),用于在各方之间安全地传输信息。传统的 JWT
主要包含三个部分:
- Header - 头部信息
- Payload - 载荷数据
- Signature - 签名信息
传统 JWT
采用签名机制来保证数据的完整性和来源可信,但其载荷内容是 Base64 编码的,这意味着任何人都可以解码查看其中的内容。
JWT 的不足之处
- 数据可见性:载荷内容虽经过签名但未加密,敏感信息容易泄露
- 隐私保护有限:无法满足对数据机密性的高要求场景
- 合规风险:在处理个人敏感信息时可能不符合数据保护法规
JWE 的优势
JWE
(JSON Web Encryption) 在 JWT
基础上增加了加密层,提供以下优势:
- 数据机密性:对整个载荷进行加密,确保内容不可见
- 更强安全性:结合签名和加密,提供双重保护
- 合规支持:满足 GDPR、HIPAA 等数据保护要求
与 JWT 的对比
特性 | JWT | JWE |
---|---|---|
数据保护 | 仅签名,内容可见 | 加密保护,内容不可见 |
安全级别 | 中等 | 高 |
性能开销 | 低 | 较高 |
适用场景 | 公开信息传输 | 敏感数据传输 |
实现复杂度 | 简单 | 复杂 |
// 普通 JWT 示例
String jwt = Jwts.builder().setSubject("user123").claim("role", "admin").signWith(secretKey).compact();// JWE 示例
String jwe = Jwts.builder().setSubject("user123").claim("role", "admin").encryptWith(encryptionKey, JweAlgorithm.DIR, JweEncryption.A256GCM).compact();
使用场景
敏感数据传输
当需要在 JWT
中包含敏感信息时,如用户详细资料、权限列表等,使用 JWE
可以确保这些信息不会被第三方窃取。
合规性要求
在金融、医疗等行业,数据保护法规要求对敏感信息进行加密处理,JWE
可以满足这类合规性需求。
内部系统通信
微服务架构中,服务间传输包含业务敏感数据的令牌时,JWE
提供了更好的安全保障。
防止信息泄露
避免在日志、浏览器缓存中暴露用户敏感信息,防止中间人攻击获取载荷内容。
Spring Boot 应用中的实践
添加依赖
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.11.5</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.11.5</version><scope>runtime</scope>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.11.5</version><scope>runtime</scope>
</dependency>
配置 JWE 加密密钥
@Configuration
public class JweConfig {@Beanpublic SecretKey jweKey() {// 生成 256 位密钥用于 AES 加密return Keys.secretKeyFor(SignatureAlgorithm.HS512);}
}
创建 JWE Token
@Service
public class TokenService {@Autowiredprivate SecretKey jweKey;public String createJweToken(String username, List<String> roles) {return Jwts.builder().setSubject(username).claim("roles", roles).claim("created", System.currentTimeMillis()).encryptWith(jweKey, JweAlgorithm.DIR, JweEncryption.A256GCM).setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1小时过期.compact();}public Claims parseJweToken(String jweToken) {return Jwts.parserBuilder().decryptWith(jweKey).build().parseEncryptedClaims(jweToken);}
}
在安全过滤器中使用
@Component
public class JweAuthenticationFilter extends OncePerRequestFilter {@Autowiredprivate TokenService tokenService;@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {String authHeader = request.getHeader("Authorization");if (authHeader != null && authHeader.startsWith("Bearer ")) {String jweToken = authHeader.substring(7);try {Claims claims = tokenService.parseJweToken(jweToken);String username = claims.getSubject();List<String> roles = (List<String>) claims.get("roles");// 创建认证对象UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, null, roles.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList()));SecurityContextHolder.getContext().setAuthentication(authentication);} catch (JwtException e) {logger.error("JWE token 解析失败", e);}}filterChain.doFilter(request, response);}
}
控制器中的应用
@RestController
@RequestMapping("/api")
public class UserController {@Autowiredprivate TokenService tokenService;@PostMapping("/login")public ResponseEntity<String> login(@RequestBody LoginRequest request) {// 验证用户凭据if (authenticate(request.getUsername(), request.getPassword())) {List<String> roles = getUserRoles(request.getUsername());// 创建 JWE tokenString jweToken = tokenService.createJweToken(request.getUsername(), roles);return ResponseEntity.ok(jweToken);}return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();}@GetMapping("/profile")public ResponseEntity<UserProfile> getProfile(Authentication authentication) {String username = authentication.getName();UserProfile profile = getUserProfile(username);return ResponseEntity.ok(profile);}
}
总结
JWE
作为 JWT
的增强版本,在数据安全性方面提供了显著优势:
- 更强的安全性:通过对载荷内容进行加密,确保敏感信息不被泄露
- 合规性支持:满足 GDPR、HIPAA 等数据保护法规的要求
- 适用场景明确:特别适合处理敏感数据传输和高安全要求的环境
- 集成便利:在 Spring Boot 等现代框架中可以方便地集成和使用
然而,JWE
也带来了额外的复杂性和性能开销,因此在选择使用时需要根据具体的安全需求和性能要求进行权衡。对于包含敏感信息的令牌传输,JWE
是一个值得推荐的安全解决方案。
针对以上内容有任何疑问或者建议欢迎留言讨论。
创作不易,欢迎一键三连~~~