RSA非对称加密的Java实现及示例应用
核心概念
- 非对称加密:使用公钥加密、私钥解密
- 密钥对:公钥(公开)和私钥(保密)
- 典型应用:数据加密、数字签名
Java实现代码
import java.security.*;
import java.util.Base64;
public class RSAExample {
public static void main(String[] args) throws Exception {
// 1. 生成密钥对
KeyPair keyPair = generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String originalMessage = "重要机密数据: 42";
System.out.println("原始消息: " + originalMessage);
// 2. 加密示例
String encryptedMsg = encrypt(originalMessage, publicKey);
System.out.println("加密消息: " + encryptedMsg);
// 3. 解密示例
String decryptedMsg = decrypt(encryptedMsg, privateKey);
System.out.println("解密消息: " + decryptedMsg);
// 4. 数字签名示例
String signature = sign(originalMessage, privateKey);
System.out.println("数字签名: " + signature);
// 5. 签名验证
boolean isValid = verify(originalMessage, signature, publicKey);
System.out.println("签名验证: " + (isValid ? "有效" : "无效"));
}
// 生成RSA密钥对(2048位)
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
return keyGen.generateKeyPair();
}
// RSA加密
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());
return Base64.getEncoder().encodeToString(encryptedBytes);
}
// RSA解密
public static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(cipher.doFinal(encryptedBytes));
}
// 数字签名(SHA256withRSA)
public static String sign(String plainText, PrivateKey privateKey) throws Exception {
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(privateKey);
privateSignature.update(plainText.getBytes());
byte[] signature = privateSignature.sign();
return Base64.getEncoder().encodeToString(signature);
}
// 签名验证
public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {
Signature publicSignature = Signature.getInstance("SHA256withRSA");
publicSignature.initVerify(publicKey);
publicSignature.update(plainText.getBytes());
byte[] signatureBytes = Base64.getDecoder().decode(signature);
return publicSignature.verify(signatureBytes);
}
}
典型应用场景
1. 安全数据传输
// 客户端:用服务器公钥加密数据
String clientData = "用户凭证: ABC-123";
String encrypted = encrypt(clientData, serverPublicKey);
// 服务器:用自己的私钥解密
String decrypted = decrypt(encrypted, serverPrivateKey);
2. 数字签名(防篡改)
String document = "合同条款...";
String signature = sign(document, senderPrivateKey);
// 接收方:验证签名
boolean valid = verify(document, signature, senderPublicKey);
3. 登录令牌验证
// 认证服务器生成令牌
String token = "user=admin|expiry=20231231";
String signedToken = sign(token, serverPrivateKey);
// 客户端携带令牌:token + "|" + signedToken
// 资源服务器验证
String[] parts = token.split("\\|");
boolean valid = verify(parts[0], parts[1], serverPublicKey);
关键注意事项
- 密钥长度:至少使用2048位(3072位更安全)
- 加密限制:RSA单次加密数据长度 < 密钥长度-11字节
- AES密钥处理:
// 实际应用中应结合AES加密数据,用RSA加密AES密钥
String aesKey = "AES-256密钥";
String encryptedKey = encrypt(aesKey, rsaPublicKey);
-
密钥存储:
- 公钥:可公开发布(PEM格式)
- 私钥:使用HSM或密钥库保护(如Java KeyStore)
-
填充方案:推荐
RSA/ECB/OAEPWithSHA-256AndMGF1Padding
安全增强建议
- 定期轮换密钥(每年至少一次)
- 使用硬件安全模块(HSM)保护私钥
- 敏感操作添加时间戳防重放攻击
- 完整实现应包含异常处理和日志审计
此文实现展示了RSA非对称加密的核心功能,实际系统需结合具体安全需求进行扩展。