本文目录导读:

我来详细说明Java RSA加密解密的实操案例。
基础RSA工具类
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RSAUtil {
// 生成RSA密钥对
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048); // 推荐2048位
return generator.generateKeyPair();
}
// 公钥加密
public static String encrypt(String data, String publicKeyStr) throws Exception {
PublicKey publicKey = getPublicKey(publicKeyStr);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(data.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
// 私钥解密
public static String decrypt(String encryptedData, String privateKeyStr) throws Exception {
PrivateKey privateKey = getPrivateKey(privateKeyStr);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decryptedBytes, "UTF-8");
}
// 获取公钥
public static PublicKey getPublicKey(String base64PublicKey) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(base64PublicKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(spec);
}
// 获取私钥
public static PrivateKey getPrivateKey(String base64PrivateKey) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(base64PrivateKey);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(spec);
}
// 密钥转字符串
public static String keyToString(Key key) {
return Base64.getEncoder().encodeToString(key.getEncoded());
}
}
完整使用示例
public class RSADemo {
public static void main(String[] args) {
try {
// 1. 生成密钥对
System.out.println("=== 生成密钥对 ===");
KeyPair keyPair = RSAUtil.generateKeyPair();
String publicKeyStr = RSAUtil.keyToString(keyPair.getPublic());
String privateKeyStr = RSAUtil.keyToString(keyPair.getPrivate());
System.out.println("公钥: " + publicKeyStr);
System.out.println("私钥: " + privateKeyStr);
// 2. 加密
System.out.println("\n=== 加密 ===");
String originalData = "Hello, RSA加密!";
String encryptedData = RSAUtil.encrypt(originalData, publicKeyStr);
System.out.println("原始数据: " + originalData);
System.out.println("加密结果: " + encryptedData);
// 3. 解密
System.out.println("\n=== 解密 ===");
String decryptedData = RSAUtil.decrypt(encryptedData, privateKeyStr);
System.out.println("解密结果: " + decryptedData);
} catch (Exception e) {
e.printStackTrace();
}
}
}
处理大文本数据的分段加密
import java.util.ArrayList;
import java.util.List;
public class RSALargeDataUtil {
private static final int MAX_ENCRYPT_BLOCK = 117; // RSA 2048位加密最大块大小
private static final int MAX_DECRYPT_BLOCK = 128; // RSA 2048位解密最大块大小
// 分段加密
public static String encryptLargeData(String data, String publicKeyStr) throws Exception {
PublicKey publicKey = RSAUtil.getPublicKey(publicKeyStr);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] dataBytes = data.getBytes("UTF-8");
int inputLength = dataBytes.length;
List<byte[]> resultList = new ArrayList<>();
for (int offset = 0; offset < inputLength; offset += MAX_ENCRYPT_BLOCK) {
int length = Math.min(inputLength - offset, MAX_ENCRYPT_BLOCK);
byte[] encryptedBlock = cipher.doFinal(dataBytes, offset, length);
resultList.add(encryptedBlock);
}
// 合并所有加密块
byte[] resultBytes = new byte[resultList.stream().mapToInt(b -> b.length).sum()];
int destPos = 0;
for (byte[] block : resultList) {
System.arraycopy(block, 0, resultBytes, destPos, block.length);
destPos += block.length;
}
return Base64.getEncoder().encodeToString(resultBytes);
}
// 分段解密
public static String decryptLargeData(String encryptedData, String privateKeyStr) throws Exception {
PrivateKey privateKey = RSAUtil.getPrivateKey(privateKeyStr);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] dataBytes = Base64.getDecoder().decode(encryptedData);
int inputLength = dataBytes.length;
List<byte[]> resultList = new ArrayList<>();
for (int offset = 0; offset < inputLength; offset += MAX_DECRYPT_BLOCK) {
int length = Math.min(inputLength - offset, MAX_DECRYPT_BLOCK);
byte[] decryptedBlock = cipher.doFinal(dataBytes, offset, length);
resultList.add(decryptedBlock);
}
// 合并所有解密块
byte[] resultBytes = new byte[resultList.stream().mapToInt(b -> b.length).sum()];
int destPos = 0;
for (byte[] block : resultList) {
System.arraycopy(block, 0, resultBytes, destPos, block.length);
destPos += block.length;
}
return new String(resultBytes, "UTF-8");
}
}
实用的密钥文件管理
import java.io.*;
import java.nio.file.*;
public class RSAKeyManager {
// 保存密钥到文件
public static void saveKeyToFile(String keyStr, String filePath) throws IOException {
Files.write(Paths.get(filePath), keyStr.getBytes("UTF-8"));
}
// 从文件读取密钥
public static String loadKeyFromFile(String filePath) throws IOException {
byte[] bytes = Files.readAllBytes(Paths.get(filePath));
return new String(bytes, "UTF-8").trim();
}
// 保存密钥对
public static void saveKeyPair(KeyPair keyPair, String publicKeyPath, String privateKeyPath) throws IOException {
saveKeyToFile(RSAUtil.keyToString(keyPair.getPublic()), publicKeyPath);
saveKeyToFile(RSAUtil.keyToString(keyPair.getPrivate()), privateKeyPath);
}
// 从文件加载密钥对
public static KeyPair loadKeyPair(String publicKeyPath, String privateKeyPath) throws Exception {
PublicKey publicKey = RSAUtil.getPublicKey(loadKeyFromFile(publicKeyPath));
PrivateKey privateKey = RSAUtil.getPrivateKey(loadKeyFromFile(privateKeyPath));
return new KeyPair(publicKey, privateKey);
}
}
完整应用示例
public class RSAApplication {
public static void main(String[] args) {
try {
// 1. 生成并保存密钥
System.out.println("=== 生成并保存密钥 ===");
KeyPair keyPair = RSAUtil.generateKeyPair();
RSAKeyManager.saveKeyPair(keyPair, "public_key.pem", "private_key.pem");
System.out.println("密钥已保存到文件");
// 2. 从文件加载密钥
System.out.println("\n=== 从文件加载密钥 ===");
KeyPair loadedKeyPair = RSAKeyManager.loadKeyPair("public_key.pem", "private_key.pem");
// 3. 测试加密解密
String message = "这是一个测试消息,包含特殊字符!@#$%^&*()";
System.out.println("原始消息: " + message);
// 加密
String encrypted = RSAUtil.encrypt(message,
RSAUtil.keyToString(loadedKeyPair.getPublic()));
System.out.println("加密后: " + encrypted);
// 解密
String decrypted = RSAUtil.decrypt(encrypted,
RSAUtil.keyToString(loadedKeyPair.getPrivate()));
System.out.println("解密后: " + decrypted);
// 验证
System.out.println("\n验证结果: " + message.equals(decrypted));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Maven依赖
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.15</version>
</dependency>
注意事项
- 密钥长度:推荐至少使用2048位
- 填充方式:使用PKCS1Padding
- 数据长度:RSA加密有长度限制(117字节/2048位密钥)
- 性能考虑:RSA不适合加密大量数据,建议配合AES使用
- 密钥管理:私钥必须妥善保管,不能泄露
- Base64编码:加密结果使用Base64编码便于传输
这个实操案例涵盖了RSA加密解密的完整流程,包括密钥生成、加解密操作、大文本处理以及密钥文件管理等功能。