rsa非对称加密方式
1、依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.9</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo1</name>
<description>Demo project for Spring Boot</description>
<!--统一编码和JAVA版本-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--jwt-->
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.4.0</version>
</dependency>
<!--jwt rsa-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
</dependency>
<!--LomBok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--Spring Boot Web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、user对象
package com.example.demo1.jwt_rsa.entity;
import lombok.Data;
/**
* @author admin
*/
@Data
public class User {
private Integer id;
private String username;
private String password;
}
3、Jwtutils
package com.example.demo1.jwt_rsa.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.demo1.jwt_rsa.entity.User;
import com.google.common.base.Throwables;
import io.jsonwebtoken.*;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.*;
/**
* @author admin
*/
public class JWTUtils {
private static Logger log = LoggerFactory.getLogger("JWTUtils");
/**
* 获取token
* @param u user
* @return token
*/
public static String getToken(User u, PrivateKey privateKey) throws NoSuchAlgorithmException {
Calendar instance = Calendar.getInstance();
//默认令牌过期时间1小时
instance.add(Calendar.HOUR, 1);
JwtBuilder bd = Jwts.builder() // 开启jwtBuilder的内容添加
.claim("id", u.getId())
.claim("username", u.getUsername())
.claim("password", u.getPassword())
// .addClaims(claims) // 添加携带信息
.setExpiration(instance.getTime()); // 设置过期时间
String userToken = bd
.signWith(SignatureAlgorithm.RS256, privateKey) // 指定签名的算法和密钥,其中RS256规定了非对称签名,私钥通过RSA生成
.compact(); // 完成内容添加
return userToken;
}
/**
* 验证token合法性 成功返回token
*/
public static Jws<Claims> verify(String userToken, PublicKey publicKey) throws NoSuchAlgorithmException {
return Jwts.parser()
.setSigningKey(publicKey)
.parseClaimsJws(userToken);
}
// 生成RSA公私钥
// <其中salt为自定义字符串,相对而言越复杂越好>
public static Map<String, Object> createKey(String salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
// 首先生成一个KeyPairGenerator对象,用于生成非对称公私钥,实例化时指定类型为“RSA”
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
// 根据salt创建一个随机源
SecureRandom secureRandom = new SecureRandom(salt.getBytes());
// 对KeyPairGenerator对象执行初始化,其中1024代表密钥大小,一般就取1024即可;参数二为随机源
keyPairGenerator.initialize(1024, secureRandom);
// 生成公私钥,“genKeyPair()”方法与“generateKeyPair()”方法相同,都能用
KeyPair keyPair = keyPairGenerator.genKeyPair();
// 创建一个Map保存公私钥并返回,可根据业务具体需求自己修改
Map<String,Object> keyMap = new HashMap<>();
keyMap.put("publicKey",keyPair.getPublic()); // 此时值的类型为PublicKey
keyMap.put("privateKey",keyPair.getPrivate()); // 此时值的类型为PrivateKey
return keyMap;// 若需要将密钥写入文件,可以对生成的公私钥执行“对象名.getEncoded()”方法将密钥转换为“byte[]”,再写入文件
}
public static String Key2Base64(Key key){
return new String(Base64.encodeBase64Chunked(key.getEncoded()));
}
public static PrivateKey Base642PrivateKey(String base64) throws NoSuchAlgorithmException, InvalidKeySpecException {
//base64转key
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(base64));
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
Map<String, Object> zx = createKey("zx");
User u = new User();
u.setId(1);
u.setUsername("wang");
u.setPassword("123");
String token = getToken(u, (PrivateKey) zx.get("privateKey"));
Jws<Claims> verify = verify(token, (PublicKey) zx.get("publicKey"));
System.out.println(verify.getBody());
}
}