public class RSATest {
public static void main(String[] args) throws Exception {
// 生成公钥和私钥
KeyPair keyPair = generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 要加密的信息
String message = "This is a very long message that needs to be encrypted in chunks. It should be longer than a single RSA encryption block to demonstrate chunking.";
// 加密
byte[] encryptedMessage = encrypt(message.getBytes(), privateKey);
//byte[] encryptedMessage = encrypt(Base64.getDecoder().decode("XXX"), privateKey);
// 解密
byte[] decryptedMessage = decrypt(encryptedMessage, publicKey);
// 输出结果
System.out.println("Original message: " + message);
System.out.println("Decrypted message: " + new String(decryptedMessage));
/* ----------- 以下测试序列化 ----------*/
PublicKey publicKey2 = getPublicKey(convertPublic(publicKey));
PrivateKey privateKey2 = getPrivateKey(convertPrivate(privateKey));
// 加密
byte[] encryptedMessage2 = encrypt(message.getBytes(), privateKey2);
String dataStr = Base64.getEncoder().encodeToString(encryptedMessage2);
System.out.println("密文: " + dataStr);
// 解密
byte[] decryptedMessage2 = decrypt(Base64.getDecoder().decode(dataStr), publicKey2);
System.out.println("Original message2: " + message);
System.out.println("Decrypted message2: " + new String(decryptedMessage2));
}
private static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
return keyGen.generateKeyPair();
}
private static byte[] encrypt(byte[] message, Key publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
int maxLength = 109;
List<byte[]> chunks = new ArrayList<>();
for (int i = 0; i < message.length; i += maxLength) {
byte[] chunk = new byte[Math.min(maxLength, message.length - i)];
System.arraycopy(message, i, chunk, 0, chunk.length);
chunks.add(cipher.doFinal(chunk));
}
return combineChunks(chunks);
}
private static byte[] decrypt(byte[] encryptedMessage, Key privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
int chunkSize = 128; // 对于1024位的密钥
List<byte[]> chunks = new ArrayList<>();
for (int i = 0; i < encryptedMessage.length; i += chunkSize) {
byte[] chunk = new byte[chunkSize];
System.arraycopy(encryptedMessage, i, chunk, 0, chunkSize);
chunks.add(cipher.doFinal(chunk));
}
return combineChunks(chunks);
}
private static byte[] combineChunks(List<byte[]> chunks) {
int totalLength = chunks.stream().mapToInt(chunk -> chunk.length).sum();
byte[] result = new byte[totalLength];
int currentPosition = 0;
for (byte[] chunk : chunks) {
System.arraycopy(chunk, 0, result, currentPosition, chunk.length);
currentPosition += chunk.length;
}
return result;
}
public static String convertPublic(PublicKey publicKey) {
return Base64.getEncoder()
.withoutPadding()
.encodeToString(publicKey.getEncoded());
}
public static String convertPrivate(PrivateKey privateKey) {
return Base64.getEncoder()
.withoutPadding()
.encodeToString(privateKey.getEncoded());
}
@SneakyThrows
public static PublicKey getPublicKey(String sshPublicKey) {
sshPublicKey = sshPublicKey.replace("\n", "");
byte[] publicKeyBytes = Base64.getDecoder().decode(sshPublicKey);
// 创建X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
return KeyFactory.getInstance("RSA").generatePublic(keySpec);
}
@SneakyThrows
public static PrivateKey getPrivateKey(String sshPrivateKey) {
sshPrivateKey = sshPrivateKey.replace("\n", "");
byte[] byteKey = Base64.getDecoder().decode(sshPrivateKey);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(byteKey);
return KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec);
}
}