公私钥非对称加密 生成和验证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

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

相关推荐
我认不到你5 分钟前
antd proFromSelect 懒加载+模糊查询
前端·javascript·react.js·typescript
集成显卡8 分钟前
axios平替!用浏览器自带的fetch处理AJAX(兼容表单/JSON/文件上传)
前端·ajax·json
焚琴煮鹤的熊熊野火16 分钟前
前端垂直居中的多种实现方式及应用分析
前端
我是苏苏36 分钟前
C# Main函数中调用异步方法
前端·javascript·c#
好看资源平台1 小时前
爬虫开发工具与环境搭建——环境配置
爬虫·python
转角羊儿1 小时前
uni-app文章列表制作⑧
前端·javascript·uni-app
大G哥1 小时前
python 数据类型----可变数据类型
linux·服务器·开发语言·前端·python
hong_zc1 小时前
初始 html
前端·html
赛丽曼1 小时前
Python中的HTML
python·html
小小吱1 小时前
HTML动画
前端·html