我有解密的問題(也許錯了加密,太)與RSA在Java中的數據。 我想在字符串一些更多的信息加密的公鑰,然後解密此公鑰和與它加密的東西(我用的2048 RSA):錯誤RSA數據爪哇解密:javax.crypto.BadPaddingException:解密錯誤
加密:
public void saveExportToFile(String fileName, BigInteger mod, BigInteger exp, String info, PublicKey puk) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(baos));
try {
oout.writeObject(mod);
oout.writeObject(exp);
oout.writeChars(info);
oout.close();
baos.close();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, puk);
FileOutputStream fos = new FileOutputStream(new File(fileName));
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] data = baos.toByteArray();
int i = 0;
byte[] buffer = new byte[128];
byte[] cipherData = null;
while (i < data.length) {
if (i+128 >= data.length) {
buffer = new byte[data.length - i];
System.arraycopy(data, i, buffer, 0, data.length - i);
cipherData = cipher.doFinal(buffer);
bos.write(cipherData);
} else {
System.arraycopy(data, i, buffer, 0, 128);
cipherData = cipher.doFinal(buffer);
bos.write(cipherData);
}
i += 128;
}
bos.close();
} catch (Exception e) {
throw new IOException("Unexpected error", e);
}
}
解密:
public void getDataFromRSA(String sendname, PrivateKey privateKey) {
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(sendname)));
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
int length = 0;
int allLength = 0;
byte[] buffer = new byte[128];
byte[] bufferAC = null;
byte[] outData = null;
byte[] allData = null;
byte[] tmpData = null;
while ((length = bis.read(buffer)) != -1) {
if (length < 128) {
bufferAC = new byte[length];
System.arraycopy(buffer, 0, bufferAC, 0, length);
outData = cipher.doFinal(bufferAC);
} else {
outData = cipher.doFinal(buffer); // HERE IS THE ERROR
}
allLength += outData.length;
tmpData = allData;
allData = new byte[allLength];
System.arraycopy(tmpData, 0, allData, 0, tmpData.length);
System.arraycopy(outData, 0, allData, tmpData.length, outData.length);
}
} catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | ClassNotFoundException | InvalidKeySpecException e) {
e.printStackTrace();
}
}
編輯 OK,看來我不知道密碼,因爲我以爲多。我只想使用RSA(如果可能的話),因爲我不需要多次傳輸信息(信息大小各不相同)。我已經編輯加密這樣的:
int i = 0;
byte[] buffer = new byte[245];
byte[] cipherData = null;
while (i < data.length) {
if (i+245 >= data.length) {
buffer = new byte[data.length - i];
System.arraycopy(data, i, buffer, 0, data.length - i);
} else {
System.arraycopy(data, i, buffer, 0, 245);
}
cipherData = cipher.update(buffer);
bos.write(cipherData);
i += 245;
}
bos.write(cipher.doFinal()); // HERE IS THE ERROR
bos.close();
現在我得到javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes
(緩衝區大小嚐試了較低的值)。是否因爲數據長度不是塊大小的倍數?這可以解決嗎?感謝您的回答。
您不應該使用RSA作爲分組密碼。在你的方案中,攻擊者可以簡單地將先前的塊插入密碼中的任何位置,而無需在解密期間發現它。混合加密/解密並不難,你爲什麼不努力做正確的事情? – 2014-09-06 16:46:41
對於你當前的問題:RSA有填充開銷,你應該把最多245個字節和每256個字節解密(11字節開銷)。如果必須的話,在帶有245字節加密緩衝區和256字節解密*輸入*緩衝區的循環中使用doFinal。請注意,這不會解決您的協議,只是您當前的實施。 – 2014-09-06 16:50:07
謝謝,我現在使用混合加密技術現在沒有問題 – d3im 2014-09-07 19:26:55