前言
这是我在这个网站整理的笔记,关注我,接下来还会持续更新。 作者:神的孩子都在歌唱
公私钥非对称加密 生成和验证JSON Web Token
-
- [什么是JSON Web Token (JWT)](#什么是JSON Web Token (JWT))
- Java程序中生成和验证JWT
- 代码解析
什么是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。具体分析如下:
- 导入所需的包
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;
- 生成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公私钥对,将公私钥分别存储在publicKey
和privateKey
变量中,并将它们对应的字符串分别存储在publicKeyString
和privateKeyString
变量中。
- 将公私钥字符串转换为公私钥对象
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);
将公私钥对应的字符串转换成公私钥对象,以便后续使用。
- 构建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,设置了主题、签发时间、过期时间和一个自定义声明,并使用私钥进行签名。
- 验证JWT token
java
Jws<Claims> jws = Jwts.parser()
.setSigningKey(publicKey)
.parseClaimsJws(jwtToken);
使用公钥验证JWT token,并将解析后的结果存储在jws
变量中。
- 获取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
转载说明:务必注明来源,附带本人博客连接。