本文介紹了如何在Java中對大數據進行RSA加解密的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!
問題描述
我正在嘗試使用RSA和OAEP對實際更大的數據(例如10 KB)執行非對稱加密和解密。
許多Stackoverflow文章都提到使用混合方法[不對稱+對稱],但我并不希望這樣。我特意要求使用非對稱加密。
我對加密和解密密碼進行了如下初始化:
mDecryptCipher = Cipher.getInstance("RSA/None/OAEPPadding", new BouncyCastleProvider());
mDecryptCipher.init(Cipher.DECRYPT_MODE, mPrivateKey);
Log.d(TAG, "Decrypt Cipher is successfully created");
mEncryptCipher = Cipher.getInstance("RSA/None/OAEPPadding", new BouncyCastleProvider());
mEncryptCipher.init(Cipher.ENCRYPT_MODE, mPublicKey);
Log.d(TAG, "Encrypt Cipher is successfully created");
以下是我嘗試用來加密或解密大小為10 KB的大型數據的代碼。
// Encrypt
byte[] encryptedPayload = mEncryptCipher.doFinal(payload);
// Decrypt
byte[] decryptedPayload = mDecryptCipher.doFinal(payload);
以下是我收到的異常:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block
at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2205)
請告訴我如何對大數據執行RSA加密和解密。
推薦答案
Java Cipher對象允許我們檢索塊大小,并使用該對象執行一種重復的加密和解密,從而克服
RSA塊
加密邏輯如下:
public byte[] encrypt(String data) {
Log.d(TAG, "Encryption begins");
byte[] payload = data.getBytes(StandardCharsets.UTF_8);
int payloadLength = payload.length;
int blockSize = mEncryptCipher.getBlockSize();
Log.d(TAG, "blockSize: " + blockSize + "; payloadLength: " + payloadLength);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
int start = 0, end = 0;
while (end < payloadLength) {
end = end + blockSize;
if (end > payloadLength) {
end = payloadLength;
}
Log.d(TAG, "start: " + start + "; end: " + end + "; block: " + (end - start));
try {
byte[] encryptedSlice = mEncryptCipher.doFinal(payload, start, (end - start));
Log.d(TAG, "Encrypted Slice Length: " + encryptedSlice.length);
stream.write(encryptedSlice);
start = end;
} catch (IOException | BadPaddingException | IllegalBlockSizeException e) {
Log.e(TAG, "update failed");
e.printStackTrace();
break;
}
}
byte[] encryptedPayload = stream.toByteArray();
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, "encryptedPayload length: " + encryptedPayload.length);
byte[] base64EncryptedPayload = org.apache.commons.codec.binary.Base64.encodeBase64(encryptedPayload);
Log.d(TAG, "base64EncryptedPayload length: " + base64EncryptedPayload.length);
Log.d(TAG, "Encryption ends");
return base64EncryptedPayload;
}
解密邏輯如下:
public String decrypt(byte[] base64EncodedData) {
Log.d(TAG, "Decryption begins");
Log.d(TAG, "base64EncodedData length: " + base64EncodedData.length);
byte[] encryptedData = org.apache.commons.codec.binary.Base64.decodeBase64(base64EncodedData);
Log.d(TAG, "encryptedData length: " + encryptedData.length);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
int payloadLength = encryptedData.length;
int blockSize = mDecryptCipher.getBlockSize();
int start = 0, end = 0;
while (start < payloadLength) {
end = end + blockSize;
if (end > payloadLength) {
end = payloadLength;
}
Log.d(TAG, "start: " + start + "; end: " + end + "; block: " + (end - start));
try {
byte[] decryptedBlockData = mDecryptCipher.doFinal(encryptedData, start, (end - start));
Log.d(TAG, "decryptedBlockData Length: " + decryptedBlockData.length);
stream.write(decryptedBlockData);
start = end;
} catch (BadPaddingException | IllegalBlockSizeException | IOException e) {
Log.e(TAG, "Slicing failed");
e.printStackTrace();
break;
}
}
String payload = stream.toString();
try {
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
Log.d(TAG, "Decryption ends");
return payload;
}
請注意,在我的例子中,以下是Cipher對象的詳細信息:
EncryptCipher:
getBlockSize: 470
getAlgorithm: RSA/None/OAEPPadding
getProvider Name: BC
getProvider Info: BouncyCastle Security Provider v1.70
解密密碼:
getBlockSize: 512
getAlgorithm: RSA/None/OAEPPadding
getProvider Name: BC
getProvider Info: BouncyCastle Security Provider v1.70
我也愿意接受任何更好的解決方案。
這篇關于如何在Java中對大數據進行RSA加解密的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,