Java使用SpringBoot生成RSA密钥文件对及校验
Java 使用 SpringBoot 生成 RSA 密钥文件对及校验
1. 新建 SpringBoot 项目
2. 编写代码
2.1 编写 application.yml 文件
SystemConfig:
rsa-keypair:
# 加密方式
algorithm: RSA
# 初始化大小
key-size: 1024
# 公钥文件
public-key-file: D://publicKey
# 私钥文件
private-key-file: D://priavteKey
2.2 编写配置类用于读取 YAML 配置文件属性
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* @Author: Arther Lee
* @Description: 生成密钥对的配置文件
* @Date: create in 2022-01-29 15:11
*/
@Component
public class GenerateKeyPairConfig {
@Value("${SystemConfig.rsa-keypair.algorithm}")
private String algorithm;
@Value("${SystemConfig.rsa-keypair.key-size}")
private Integer keySize;
@Value("${SystemConfig.rsa-keypair.public-key-file}")
private String publicKeyFile;
@Value("${SystemConfig.rsa-keypair.private-key-file}")
private String privateKeyFile;
/**
* 获取指定加密算法
* @return 读取YAML文件的 SystemConfig.rsa-keypair.algorithm 属性
*/
public String getAlgorithm() {
return algorithm;
}
/**
* 获取密钥长度,用来初始化
* @return 读取YAML文件的 SystemConfig.rsa-keypair.key-size 属性
*/
public Integer getKeySize() {
return keySize;
}
/**
* 获取公钥存放文件
* @return 读取YAML文件的 SystemConfig.rsa-keypair.public-key-file 属性
*/
public String getPublicKeyFile() {
return publicKeyFile;
}
/**
* 获取私钥存放文件
* @return 读取YAML文件的 SystemConfig.rsa-keypair.private-key-file 属性
*/
public String getPrivateKeyFile() {
return privateKeyFile;
}
}
2.3 编写 RSA 工具类
import com.example.demo.common.GenerateKeyPairConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: Arther Lee
* @Description: 密钥对文件工具类
* @Date: create in 2022-01-28 17:08
*/
@Component
public class GenerateKeyPairUtil {
@Autowired
private GenerateKeyPairConfig KeyPairConfig;
// region 私有方法
/**
* 生成密钥对
* @return 返回map集合,其中包含publicKey与privateKey
* @throws NoSuchAlgorithmException
*/
private Map<String, Key> generateKeyPair() throws NoSuchAlgorithmException {
/**
* RSA算法要求有一个可信任的随机数源
*/
SecureRandom secureRandom = new SecureRandom();
/**
* 为RSA算法创建一个KeyPairGenerator对象
*/
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KeyPairConfig.getAlgorithm());
/**
* 利用上面的随机数据源初始化这个KeyPairGenerator对象
*/
keyPairGenerator.initialize(KeyPairConfig.getKeySize(), secureRandom);
/**
* 生成密匙对
*/
KeyPair keyPair = keyPairGenerator.generateKeyPair();
/**
* 得到公钥
*/
Key publicKey = keyPair.getPublic();
/**
* 得到私钥
*/
Key privateKey = keyPair.getPrivate();
Map<String, Key> keyPairMap = new HashMap<>();
keyPairMap.put("publicKey", publicKey);
keyPairMap.put("privateKey", privateKey);
return keyPairMap;
}
/**
* 获取文件中获取密钥对象
* @param fileName 文件名
* @return 密钥对象
*/
private Key getKeyFromFile(String fileName) {
Key key = null;
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(fileName));
key = (Key) ois.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return key;
}
/**
* 将密钥对生成到文件中
*/
private void generateKeyPairToFiles() {
ObjectOutputStream oosPublicKey = null;
ObjectOutputStream oosPrivateKey = null;
try {
Map<String, Key> keyPairMap = generateKeyPair();
Key publicKey = keyPairMap.get("publicKey");
Key privateKey = keyPairMap.get("privateKey");
oosPublicKey = new ObjectOutputStream(new FileOutputStream(KeyPairConfig.getPublicKeyFile()));
oosPrivateKey = new ObjectOutputStream(new FileOutputStream(KeyPairConfig.getPrivateKeyFile()));
oosPublicKey.writeObject(publicKey);
oosPrivateKey.writeObject(privateKey);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
/**
* 清空缓存,关闭文件输出流
*/
oosPublicKey.close();
oosPrivateKey.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// endregion 私有方法
// region 公有方法
/**
* 初始化密钥对文件
* @return 返回密钥对信息【publicKey(公钥字符串)、、privateKey(私钥字符串)】
*/
public Map<String, String> initKeyPair() {
Map<String, String> keyPairMap = new HashMap<>();
File publicFile = new File(KeyPairConfig.getPublicKeyFile());
File privateFile = new File(KeyPairConfig.getPrivateKeyFile());
/**
* 判断是否存在公钥和私钥文件
*/
if (!publicFile.exists() || !privateFile.exists()) {
generateKeyPairToFiles();
}
ObjectInputStream oisPublic = null;
ObjectInputStream oisPrivate = null;
Key publicKey = null;
Key privateKey = null;
try {
oisPublic = new ObjectInputStream(new FileInputStream(KeyPairConfig.getPublicKeyFile()));
oisPrivate = new ObjectInputStream(new FileInputStream(KeyPairConfig.getPrivateKeyFile()));
publicKey = (Key) oisPublic.readObject();
privateKey = (Key) oisPrivate.readObject();
byte[] publicKeyBytes = publicKey.getEncoded();
byte[] privateKeyBytes = privateKey.getEncoded();
String publicKeyBase64 = new BASE64Encoder().encode(publicKeyBytes);
String privateKeyBase64 = new BASE64Encoder().encode(privateKeyBytes);
/**
* 公钥字符串
*/
keyPairMap.put("publicKey", publicKeyBase64);
/**
* 私钥字符串
*/
keyPairMap.put("privateKey", privateKeyBase64);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
oisPrivate.close();
oisPublic.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return keyPairMap;
}
/**
* 加密方法
* @param source 源数据
* @return 加密后的字符串
*/
public String encrypt(String source) {
Key publicKey = getKeyFromFile(KeyPairConfig.getPublicKeyFile());
BASE64Encoder encoder = new BASE64Encoder();
String encryptSource = null;
try {
/**
* 得到Cipher对象来实现对源数据的RSA加密
*/
Cipher cipher = Cipher.getInstance(KeyPairConfig.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] bytes = source.getBytes();
/**
* 执行加密操作
*/
encryptSource = encoder.encode(cipher.doFinal(bytes));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return encryptSource;
}
/**
* 解密方法
* @param source 密文
* @return 解密后的字符串
*/
public String decrypt(String source) {
Key privateKey = getKeyFromFile(KeyPairConfig.getPrivateKeyFile());
BASE64Decoder decoder = new BASE64Decoder();
String decryptSource = null;
try {
/**
* 得到Cipher对象对已用公钥加密的数据进行RSA解密
*/
Cipher cipher = Cipher.getInstance(KeyPairConfig.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
/**
* 执行解密操作
*/
byte[] bytes = decoder.decodeBuffer(source);
decryptSource = new String(cipher.doFinal(bytes), "UTF-8");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return decryptSource;
}
// endregion 公有方法
}
3. 项目测试
3.1 测试代码
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.Map;
@SpringBootTest
class DemoApplicationTests {
@Autowired
GenerateKeyPairUtil keyPairUtil;
@Test
void contextLoads() {
Map<String, String> keyPairMap = keyPairUtil.initKeyPair();
String publicKey = keyPairMap.get("publicKey");
String privateKey = keyPairMap.get("privateKey");
System.out.println("公钥:");
System.out.println(publicKey);
System.out.println();
System.out.println("私钥:");
System.out.println(privateKey);
System.out.println();
String source = "Hello World";
System.out.println("待加密字符串:" + source);
System.out.println();
String strEncrypt = keyPairUtil.encrypt(source);
System.out.println("加密后的字符串:");
System.out.println(strEncrypt);
System.out.println();
String strDecrypt = keyPairUtil.decrypt(strEncrypt);
System.out.println("解密后的字符串:");
System.out.println(strDecrypt);
}
}
3.2 测试结果
公钥:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCURAtxRGI7Of19MOb2XoTXFjBG52kr7b11DRJ4
UnyThIuKUjzNSQnW+a1T3fHMfF0w22NiyE2lRpYZ+W6z7MsOhr/EOrXHcFhRd3+bc+j+56aLo8Mp
rYnxBmcc49J5uN8ztg4XSLf4DyEx3CmSh8/mzJxOtoEYDKGL1RapQu2l/QIDAQAB
私钥:
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJREC3FEYjs5/X0w5vZehNcWMEbn
aSvtvXUNEnhSfJOEi4pSPM1JCdb5rVPd8cx8XTDbY2LITaVGlhn5brPsyw6Gv8Q6tcdwWFF3f5tz
6P7npoujwymtifEGZxzj0nm43zO2DhdIt/gPITHcKZKHz+bMnE62gRgMoYvVFqlC7aX9AgMBAAEC
gYEAjl0H36qZ5+S20g6ytr3rL9vOX0a0ZcnRsSLsKTyLAdqzYg209Ci9mf4DwBPMqVyA3vjJZYCP
jbNJTYeEFJ+6GKyIXZeYYXlEzPytrScB+vfro3JUGNnDu4RtFjFPsf3iew872/Vllkq/rNnrXnze
vA7Ea0JxfUEtumdX9CgE8AECQQDo86ocAYcQO+JbX8G9RGcn8SvCieaG9dM7U3fUlrB7XrcJqDo+
ypRqEYZGcdX4iv841bFAqPPFRkhWS+TAMmm9AkEAou9npIFhC0Xe/ncICeWcIn0XHfy/e1cKTE+d
YqfB5RdUcM/qPzrdO2U7p9guscc+e6AbHyhE4MtuoSZu2hxRQQJBAKFzBunEEUSqDFaBxjeTqd7f
4hFBG9lblFtgnQNksMnAOiFiS4PrSPM+VA6MpNxOEVblm6SRs+l8rXPJw6+FAQ0CQEIR0DYt3Hsk
vxLyk4jn2ZNGpCwdxEuwdNWS5yANJJvQBQal2LgBF5qxJyqdh/nA8H5S4wyUWLHK7DZejk7VcsEC
QAn83cKhqcxArrF+jNizom3at44Ag5fdlUahb+ybSNnqeJ6qq5Tagrix6KqVImRAsW1AUQC0r+IN
4FyTzh5WQAw=
待加密字符串:Hello World
加密后的字符串:
IerO2h4VHRN9cD3PoyD8oBlW9yHXu6ZJa9XO1zIi3JhQFIOMye18nx7pR2gI7dr9h41Q5mRiNjz7
3PDu5tLF7nyoIF0IcUHk3Dv4JMfQnfwGEEScatSjai1doIFnpBhUoDJEUY2/qBAUbt14/J1nhKn6
BgeHz0lYrvTVB2TAmus=
解密后的字符串:
Hello World
本文来自博客园,作者:爱Ni说不出口,转载请注明原文链接:https://www.cnblogs.com/ArtherLee/p/15855343.html
分类:
Java
标签:
Java
, SpringBoot
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现