![](/img/trans.png)
[英]BadPaddingException When Decrypting Separately using AES in Java
[英]Security- decrypting in java “BadPaddingException”
我正在加密字符串並將其寫入文本文件。 為了解密內容,我正在讀取該文件並打印解密后的數據。 當我用一個字符串值測試我的代碼時,它可以很好地加密和解密。 但是,當我添加更多字符串進行加密時,加密工作正常,但是解密給了我這個異常“ javax.crypto.BadPaddingException:給定的最終塊未正確填充”
這是我的代碼。 請幫忙!
// these are initialized in main
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
ecipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
dcipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
// catches ..
// it will take a string and the file that will have the encrypted strings
private static void encrypt(String s, OutputStream os) throws IllegalBlockSizeException, BadPaddingException {
try {
byte[] buf = s.getBytes();
byte[] b = ecipher.doFinal(buf);
os.write(b);
// this is to write a new line after writing each encrypted value and avoid overwriting
os.write(System.getProperty("line.separator").getBytes());
os.flush();
os.close();
}
catch (IOException e) {
System.out.println("I/O Error:" + e.getMessage());
}
}
// this will take the file that has all of the encryptions
private static void decrypt(InputStream is) throws IllegalBlockSizeException, BadPaddingException {
try {
byte[] buf = new byte[is.available()];
is.read(buf);
byte[] decrypted = dcipher.doFinal(buf); // THE CAUSE OF THE PROBLEM!!!!
System.out.println(new String (decrypted));
is.close();
}
catch (IOException e) {
System.out.println("I/O Error:" + e.getMessage());
}
加密時,您將加密的數據寫入輸出文件,然后添加換行符,但是解密時,您似乎正在讀取文件的全部內容並將其解密,這將包括換行符,它將嘗試解密好像它是密文的一部分一樣,導致填充異常。 您還嘗試使用一個解密調用來解密所有單獨編寫的字符串,而它們需要分別解密。
我建議將加密的數據轉換為Base64, 然后再將其寫入輸出文件並附加換行符。 解密時,讀取一行,從Base64轉換回byte[]
並解密,然后對輸入中的每一行重復一次。
在加密的字節之后多余的行,應將其刪除。
問題的真正原因是使用InputStream.available()來獲取數據的大小。 此方法可以返回從0到輸入流中實際字節數的任何值,因此不適合確定輸入數據的大小。 在您的示例中,它返回一些值,並且您讀取了等於該值的字節數,但是很有可能它不是全部加密數據,並且密碼將無法正確解碼。
通常,無法確定輸入流的大小,因此您將不得不使用循環來讀取流。 解密代碼應基於以下范例:
private static byte[] decrypt( Cipher dcipher, InputStream in, int BUFFER_SIZE ) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] inputBuffer = new byte[ BUFFER_SIZE ]; // 4K or 8K are pretty good buffer size values
int r = in.read( inputBuffer );
while ( r >= 0 ) {
byte[] outputUpdate = dcipher.update( inputBuffer, 0, r );
out.write( outputUpdate );
r = in.read( inputBuffer );
}
byte[] outputFinalUpdate = dcipher.doFinal();
out.write( outputFinalUpdate );
return out.toByteArray();
}
InputStream
。 InputStream.read(byte[])
的返回值。 ByteArrayOutputStream
用作獲取可調整大小的字節數組的最簡單方法。 您也可以先使用類似於上述循環的代碼讀取整個加密數據,但沒有中間的Cipher.update()
,然后使用單個Cipher.doFinal()
調用一次性解碼它。
private static byte[] decrypt( Cipher dcipher, InputStream in, int BUFFER_SIZE ) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] inputBuffer = new byte[ BUFFER_SIZE ]; // 4K or 8K are pretty good buffer size values
int r = in.read( inputBuffer );
while ( r >= 0 ) {
out.write( inputBuffer, 0, r );
r = in.read( inputBuffer );
}
return dcipher.doFinal( out.toByteArray() );
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.