本文目录导读:

我来详细介绍Java中实现非对称加密的完整案例。
RSA非对称加密完整示例
核心工具类
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RSAEncryptionUtil {
// 生成密钥对
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048); // 密钥长度:1024/2048/4096
return generator.generateKeyPair();
}
// 公钥加密
public static String encrypt(String plainText, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encryptedBytes);
}
// 私钥解密
public static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decryptedBytes, "UTF-8");
}
// 私钥签名
public static String sign(String data, PrivateKey privateKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(data.getBytes("UTF-8"));
byte[] signBytes = signature.sign();
return Base64.getEncoder().encodeToString(signBytes);
}
// 公钥验签
public static boolean verify(String data, String signatureStr, PublicKey publicKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
signature.update(data.getBytes("UTF-8"));
return signature.verify(Base64.getDecoder().decode(signatureStr));
}
// 密钥转字符串
public static String keyToString(Key key) {
return Base64.getEncoder().encodeToString(key.getEncoded());
}
// 字符串转公钥
public static PublicKey stringToPublicKey(String keyStr) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(keyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
// 字符串转私钥
public static PrivateKey stringToPrivateKey(String keyStr) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(keyStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
}
测试示例
public class RSAEncryptionDemo {
public static void main(String[] args) {
try {
System.out.println("=== RSA非对称加密示例 ===");
// 1. 生成密钥对
KeyPair keyPair = RSAEncryptionUtil.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
System.out.println("公钥: " + RSAEncryptionUtil.keyToString(publicKey));
System.out.println("私钥: " + RSAEncryptionUtil.keyToString(privateKey));
// 2. 加解密测试
String originalData = "Hello, 这是需要加密的敏感数据!";
System.out.println("\n原始数据: " + originalData);
// 公钥加密
String encryptedData = RSAEncryptionUtil.encrypt(originalData, publicKey);
System.out.println("加密后: " + encryptedData);
// 私钥解密
String decryptedData = RSAEncryptionUtil.decrypt(encryptedData, privateKey);
System.out.println("解密后: " + decryptedData);
// 3. 签名验证测试
String signData = "需要签名的数据";
String signature = RSAEncryptionUtil.sign(signData, privateKey);
System.out.println("\n签名: " + signature);
boolean isValid = RSAEncryptionUtil.verify(signData, signature, publicKey);
System.out.println("签名验证结果: " + isValid);
// 4. 密钥持久化示例
System.out.println("\n=== 密钥持久化示例 ===");
// 保存密钥
String savedPublicKey = RSAEncryptionUtil.keyToString(publicKey);
String savedPrivateKey = RSAEncryptionUtil.keyToString(privateKey);
// 从字符串恢复密钥
PublicKey loadedPublicKey = RSAEncryptionUtil.stringToPublicKey(savedPublicKey);
PrivateKey loadedPrivateKey = RSAEncryptionUtil.stringToPrivateKey(savedPrivateKey);
// 验证恢复后的密钥可用
String testData = "测试持久化密钥";
String encrypted = RSAEncryptionUtil.encrypt(testData, loadedPublicKey);
String decrypted = RSAEncryptionUtil.decrypt(encrypted, loadedPrivateKey);
System.out.println("密钥持久化测试: " + testData.equals(decrypted));
} catch (Exception e) {
e.printStackTrace();
}
}
}
高级应用:混合加密系统
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
import java.util.Base64;
/**
* 混合加密系统:RSA + AES
* 解决RSA加密大数据的性能问题
*/
public class HybridEncryptionSystem {
private RSAEncryptionUtil rsaUtil;
public HybridEncryptionSystem() {
this.rsaUtil = new RSAEncryptionUtil();
}
/**
* 混合加密:AES加密数据,RSA加密AES密钥
*/
public static class EncryptedData {
private String encryptedKey; // RSA加密的AES密钥
private String encryptedData; // AES加密的数据
public EncryptedData(String encryptedKey, String encryptedData) {
this.encryptedKey = encryptedKey;
this.encryptedData = encryptedData;
}
public String getEncryptedKey() {
return encryptedKey;
}
public String getEncryptedData() {
return encryptedData;
}
}
/**
* 混合加密
*/
public EncryptedData hybridEncrypt(String data, PublicKey publicKey) throws Exception {
// 1. 生成AES密钥
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256); // AES-256
SecretKey aesKey = keyGen.generateKey();
// 2. AES加密数据
Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] encryptedData = aesCipher.doFinal(data.getBytes("UTF-8"));
// 3. RSA加密AES密钥
String encryptedKey = rsaUtil.encrypt(
Base64.getEncoder().encodeToString(aesKey.getEncoded()),
publicKey
);
return new EncryptedData(
encryptedKey,
Base64.getEncoder().encodeToString(encryptedData)
);
}
/**
* 混合解密
*/
public String hybridDecrypt(EncryptedData encryptedData, PrivateKey privateKey) throws Exception {
// 1. RSA解密获取AES密钥
String aesKeyStr = rsaUtil.decrypt(encryptedData.getEncryptedKey(), privateKey);
byte[] aesKeyBytes = Base64.getDecoder().decode(aesKeyStr);
SecretKey aesKey = new SecretKeySpec(aesKeyBytes, "AES");
// 2. AES解密数据
Cipher aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
aesCipher.init(Cipher.DECRYPT_MODE, aesKey);
byte[] decryptedData = aesCipher.doFinal(
Base64.getDecoder().decode(encryptedData.getEncryptedData())
);
return new String(decryptedData, "UTF-8");
}
}
// 混合加密测试
class HybridEncryptionDemo {
public static void main(String[] args) throws Exception {
System.out.println("=== 混合加密系统示例 ===");
// 生成RSA密钥对
KeyPair keyPair = RSAEncryptionUtil.generateKeyPair();
HybridEncryptionSystem hybridSystem = new HybridEncryptionSystem();
// 大数据测试
StringBuilder largeData = new StringBuilder();
for (int i = 0; i < 1000; i++) {
largeData.append("这是一段很长的测试数据,需要混合加密系统来处理。");
}
String originalData = largeData.toString();
System.out.println("原始数据长度: " + originalData.length() + " 字符");
// 混合加密
long startTime = System.currentTimeMillis();
HybridEncryptionSystem.EncryptedData encrypted =
hybridSystem.hybridEncrypt(originalData, keyPair.getPublic());
long encryptTime = System.currentTimeMillis() - startTime;
System.out.println("加密耗时: " + encryptTime + "ms");
System.out.println("加密后密钥长度: " + encrypted.getEncryptedKey().length());
System.out.println("加密后数据长度: " + encrypted.getEncryptedData().length());
// 混合解密
startTime = System.currentTimeMillis();
String decryptedData = hybridSystem.hybridDecrypt(encrypted, keyPair.getPrivate());
long decryptTime = System.currentTimeMillis() - startTime;
System.out.println("解密耗时: " + decryptTime + "ms");
System.out.println("解密后数据长度: " + decryptedData.length());
System.out.println("加解密验证: " + originalData.equals(decryptedData));
}
}
文件加密示例
import java.io.*;
import java.nio.file.*;
import java.security.*;
public class FileEncryptionUtil {
/**
* 加密文件
*/
public static void encryptFile(String sourceFile, String destFile,
PublicKey publicKey) throws Exception {
byte[] fileData = Files.readAllBytes(Paths.get(sourceFile));
String encryptedData = RSAEncryptionUtil.encrypt(
Base64.getEncoder().encodeToString(fileData),
publicKey
);
Files.write(Paths.get(destFile), encryptedData.getBytes("UTF-8"));
}
/**
* 解密文件
*/
public static void decryptFile(String sourceFile, String destFile,
PrivateKey privateKey) throws Exception {
String encryptedData = new String(
Files.readAllBytes(Paths.get(sourceFile)), "UTF-8"
);
String decryptedData = RSAEncryptionUtil.decrypt(encryptedData, privateKey);
byte[] originalData = Base64.getDecoder().decode(decryptedData);
Files.write(Paths.get(destFile), originalData);
}
public static void main(String[] args) throws Exception {
// 生成密钥对
KeyPair keyPair = RSAEncryptionUtil.generateKeyPair();
// 创建测试文件
Path testFile = Paths.get("test.txt");
Files.write(testFile, "这是文件加密测试内容".getBytes("UTF-8"));
// 加密文件
encryptFile("test.txt", "test.encrypted", keyPair.getPublic());
System.out.println("文件加密完成");
// 解密文件
decryptFile("test.encrypted", "test.decrypted.txt", keyPair.getPrivate());
System.out.println("文件解密完成");
// 验证
String original = new String(Files.readAllBytes(testFile), "UTF-8");
String decrypted = new String(Files.readAllBytes(Paths.get("test.decrypted.txt")), "UTF-8");
System.out.println("文件加解密验证: " + original.equals(decrypted));
// 清理测试文件
Files.deleteIfExists(testFile);
Files.deleteIfExists(Paths.get("test.encrypted"));
Files.deleteIfExists(Paths.get("test.decrypted.txt"));
}
}
性能对比和最佳实践
public class EncryptionBenchmark {
public static void main(String[] args) throws Exception {
KeyPair keyPair = RSAEncryptionUtil.generateKeyPair();
System.out.println("=== 加密性能测试 ===");
// 不同数据大小的加密耗时
int[] dataSizes = {100, 1000, 10000};
for (int size : dataSizes) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < size; i++) {
sb.append("A");
}
String data = sb.toString();
// RSA加密
long startTime = System.nanoTime();
String encrypted = RSAEncryptionUtil.encrypt(data, keyPair.getPublic());
long rsaTime = System.nanoTime() - startTime;
System.out.printf("RSA加密 %d 字节: %d μs%n", size, rsaTime / 1000);
}
}
}
安全注意事项
public class SecurityBestPractices {
/**
* 安全密钥管理示例
*/
public static class KeyStoreManager {
private static final String KEYSTORE_TYPE = "PKCS12";
private static final String KEY_ALIAS = "mykey";
/**
* 保存密钥到KeyStore
*/
public static void saveKeyToKeyStore(PrivateKey privateKey,
char[] password,
String keyStorePath) throws Exception {
KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
keyStore.load(null, null);
// 保存私钥
KeyStore.PrivateKeyEntry privateKeyEntry =
new KeyStore.PrivateKeyEntry(privateKey, new java.security.cert.Certificate[0]);
keyStore.setEntry(KEY_ALIAS, privateKeyEntry,
new KeyStore.PasswordProtection(password));
// 保存到文件
try (FileOutputStream fos = new FileOutputStream(keyStorePath)) {
keyStore.store(fos, password);
}
}
/**
* 从KeyStore加载私钥
*/
public static PrivateKey loadPrivateKey(char[] password,
String keyStorePath) throws Exception {
KeyStore keyStore = KeyStore.getInstance(KEYSTORE_TYPE);
try (FileInputStream fis = new FileInputStream(keyStorePath)) {
keyStore.load(fis, password);
}
return (PrivateKey) keyStore.getKey(KEY_ALIAS, password);
}
}
}
- 密钥安全:私钥必须安全存储,推荐使用KeyStore
- 数据大小限制:RSA加密数据不能超过密钥长度(如2048位=245字节)
- 填充方式:PKCS1Padding是标准填充方式
- 性能优化:大数据使用混合加密(RSA+AES)
- 签名验证:用于数据完整性验证
- 密钥长度:建议至少2048位
这个完整的示例提供了从基础到高级的RSA加密实现,涵盖了实际开发中常见的应用场景。