公私钥非对称加密 生成和验证JSON Web Token (JWT)

前言

这是我在这个网站整理的笔记,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱

公私钥非对称加密 生成和验证JSON Web Token

什么是JSON Web Token (JWT)

JSON Web Token (JWT) 是一种轻量级的身份验证和授权机制,由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。其中头部和载荷都是Base64编码的JSON对象,签名是对头部、载荷和秘钥进行加密生成的。

JWT的优点在于它是一种无状态的身份验证机制,因此可以在分布式系统中广泛使用。JWT通常作为API的身份验证机制,客户端在请求中携带JWT token,服务端通过验证JWT token来确定请求的合法性。

使用JWT作为API的身份验证机制可以避免服务器保存用户登录状态,从而提高系统的可扩展性和安全性。在实际开发中,可以根据具体需求来选择不同的加密算法和秘钥长度。

Java程序中生成和验证JWT

以下是一个Java程序,用于生成和验证JSON Web Token (JWT)。该程序使用了RSA非对称加密算法生成公私钥对,并使用私钥构建JWT token,设置了主题、签发时间、过期时间和一个自定义声明。最后,使用公钥验证JWT token,并从中获取主题信息和自定义声明。

java 复制代码
package com.ugdsec.common.auth.common.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;

public class JwtExample {

    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {

        // 生成RSA公私钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();
        String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
        String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());

        // 将公钥字符串转换为公钥对象
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
        publicKey = KeyFactory.getInstance("RSA").generatePublic(publicKeySpec);

        // 将私钥字符串转换为私钥对象
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyString);
        PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        privateKey = KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec);

        // 构建JWT token
        String jwtToken = Jwts.builder()
            .setSubject("user")
            .setIssuedAt(new Date())
            .setExpiration(new Date(System.currentTimeMillis() + 3600000))
            .signWith(SignatureAlgorithm.RS256, privateKey)
            .claim("test","sdfs")
            .compact();
        System.out.println(jwtToken);

        // 验证JWT token
        Jws<Claims> jws = Jwts.parser()
            .setSigningKey(publicKey)
            .parseClaimsJws(jwtToken);

        // 获取JWT token中的主题信息和自定义声明
        String subject = jws.getBody().getSubject();
        String test = (String) jws.getBody().get("test");
        System.out.println("Subject: " + subject);
        System.out.println("Test: " + test);
    }
}

输出结果:

代码解析

程序中使用了io.jsonwebtoken包提供的类和方法来生成和验证JWT token。具体分析如下:

  1. 导入所需的包
java 复制代码
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Date;
  1. 生成RSA公私钥对
java 复制代码
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
String publicKeyString = Base64.getEncoder().encodeToString(publicKey.getEncoded());
String privateKeyString = Base64.getEncoder().encodeToString(privateKey.getEncoded());

使用KeyPairGenerator类生成2048位的RSA公私钥对,将公私钥分别存储在publicKeyprivateKey变量中,并将它们对应的字符串分别存储在publicKeyStringprivateKeyString变量中。

  1. 将公私钥字符串转换为公私钥对象
java 复制代码
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyString);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes);
publicKey = KeyFactory.getInstance("RSA").generatePublic(publicKeySpec);

byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyString);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
privateKey = KeyFactory.getInstance("RSA").generatePrivate(privateKeySpec);

将公私钥对应的字符串转换成公私钥对象,以便后续使用。

  1. 构建JWT token
java 复制代码
String jwtToken = Jwts.builder()
    .setSubject("user")
    .setIssuedAt(new Date())
    .setExpiration(new Date(System.currentTimeMillis() + 3600000))
    .signWith(SignatureAlgorithm.RS256, privateKey)
    .claim("test","sdfs")
    .compact();
System.out.println(jwtToken);

使用Jwts.builder()方法构建JWT token,设置了主题、签发时间、过期时间和一个自定义声明,并使用私钥进行签名。

  1. 验证JWT token
java 复制代码
Jws<Claims> jws = Jwts.parser()
    .setSigningKey(publicKey)
    .parseClaimsJws(jwtToken);

使用公钥验证JWT token,并将解析后的结果存储在jws变量中。

  1. 获取JWT token中的主题信息和自定义声明
java 复制代码
String subject = jws.getBody().getSubject();
String test = (String) jws.getBody().get("test");
System.out.println("Subject: " + subject);
System.out.println("Test: " + test);

作者:神的孩子都在歌唱

本人博客:https://blog.csdn.net/weixin_46654114

转载说明:务必注明来源,附带本人博客连接。

相关推荐
ITMan彪叔几秒前
赋能UE运行态编辑平台: 网络图片下载的插件改造与复盘
前端
财经资讯数据_灵砚智能3 分钟前
基于全球经济类多源新闻的NLP情感分析与数据可视化(夜间-次晨)2026年6月6日
人工智能·python·ai·信息可视化·自然语言处理·ai编程·灵砚智能
RANxy4 分钟前
🚀 Umi Max 项目从0到1:企业级 React 脚手架实战
前端·前端框架
拾年27517 分钟前
深入理解 V8 引擎:从代码执行到垃圾回收的完整链路
前端·javascript·v8
Master_Azur21 分钟前
javaScript进阶
前端
markfeng822 分钟前
React入门教学
前端·react.js
ze_juejin23 分钟前
Object.defineProperty vs Proxy 对比总结
前端
wing9831 分钟前
我的AI编程体验:从白嫖到付费,我为什么最终留下了Codex
前端·人工智能·程序员
千寻girling39 分钟前
一周没跑步了 ,今日跑步 5KM , 哑铃+健身 20min , 俯卧撑 30 个 ;
数据结构·c++·python·算法·leetcode·职场和发展·线性回归
京东云开发者41 分钟前
京东Taro Native框架静态布局直渲提速
前端