RSA加密解密示例代码
import javax.crypto.Cipher;
import java.security.*;
import java.util.Base64;
import java.nio.charset.StandardCharsets;
import java.io.ByteArrayOutputStream;
public class RSADemo {
// 加密时每块的最大字节数,对于1024位RSA密钥,通常为117字节
private static final int MAX_ENCRYPT_BLOCK = 117;
// 解密时每块的最大字节数,对于1024位RSA密钥,通常为128字节
private static final int MAX_DECRYPT_BLOCK = 128;
public static void main(String[] args) throws Exception {
// 生成RSA密钥对
KeyPair keyPair = generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 原始文本
String originalText = "Hello, RSA Encryption!";
// 加密文本
String encryptedText = encrypt(originalText, publicKey);
System.out.println("Encrypted Text: " + encryptedText);
// 解密文本
String decryptedText = decrypt(encryptedText, privateKey);
System.out.println("Decrypted Text: " + decryptedText);
}
// 生成RSA密钥对的方法
private static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(1024);
return keyPairGenerator.generateKeyPair();
}
// 使用公钥加密文本
private static String encrypt(String plainText, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = processData(plainText.getBytes(StandardCharsets.UTF_8), cipher, MAX_ENCRYPT_BLOCK);
return Base64.getEncoder().encodeToString(encryptedData);
}
// 使用私钥解密文本
private static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = processData(Base64.getDecoder().decode(encryptedText), cipher, MAX_DECRYPT_BLOCK);
return new String(decryptedData, StandardCharsets.UTF_8);
}
// 分块处理加密或解密数据的方法
private static byte[] processData(byte[] data, Cipher cipher, int maxBlockSize) throws Exception {
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
while (inputLen - offSet > 0) {
// 确定当前块的大小
if (inputLen - offSet > maxBlockSize) {
cache = cipher.doFinal(data, offSet, maxBlockSize);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
// 将加密或解密后的块写入输出流
out.write(cache, 0, cache.length);
offSet += maxBlockSize;
}
return out.toByteArray();
}
}
为什么加密的分段大小和解密的分段大小不同:
加密分段大小 (MAX_ENCRYPT_BLOCK
): 在RSA加密中,由于使用了填充(如PKCS#1 v1.5),可加密的最大数据量小于密钥长度。对于1024位RSA密钥,有效载荷大小大约是117字节,因为需要留出空间给填充和可能的会话密钥等。
解密分段大小 (MAX_DECRYPT_BLOCK
): 解密时,数据块的大小等于密钥长度除以8。对于1024位RSA密钥,这意味着解密块的大小是128字节。这是因为在加密过程中添加的填充在解密时被移除,因此解密块可以容纳整个加密数据块(包括填充)。
如果你已经使用OpenSSL工具得到了RSA密钥对字符串(可参考https://www.cnblogs.com/ashet/p/18434822),请使用以下方法生成公钥、私钥
// 使用X509EncodedKeySpec加载公钥
private static PublicKey initPublicKey(String publicKeyStr) throws Exception {
byte[] publicKeyBytes = Base64.getDecoder().decode(publicKeyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
// 使用PKCS8EncodedKeySpec加载私钥
private static PrivateKey initPrivateKey(String privateKeyStr) throws Exception {
byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· 大模型工具KTransformer的安装
· [计算机/硬件/GPU] 显卡
2023-10-09 Docker command
2023-10-09 Install docker on CentOS _base China