2011-10-13 88 views
0

我使用javax.crypto.Cipher加密一個文件,然後解密它,但我仍然得到BadPaddingException。以下課程從輸入文件接收inputStream,輸出文件接收outputStreamBadPaddingException當解密加密流

Error

13:22:15,049 ERROR [STDERR] javax.crypto.BadPaddingException: Given final block not properly padded 
13:22:15,081 ERROR [STDERR]  at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) 
13:22:15,096 ERROR [STDERR]  at com.sun.crypto.provider.SunJCE_f.b(DashoA13*..) 
13:22:15,128 ERROR [STDERR]  at com.sun.crypto.provider.AESCipher.engineDoFinal(DashoA13*..) 
13:22:15,143 ERROR [STDERR]  at javax.crypto.Cipher.doFinal(DashoA13*..) 

Code

public class CipherAES implements Cipher { 

    private static final Logger logger = Logger.getLogger(CipherAES.class); 

    private Key key; 

    public CipherAES() { 
     this.key = generateKey(); 
    } 

    private Key generateKey() { 
     try { 
      KeyGenerator generator; 
      generator = KeyGenerator.getInstance("AES"); 
      generator.init(new SecureRandom()); 
      return generator.generateKey(); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    public void decrypt(InputStream inputStream, OutputStream outputStream) throws IOException { 
     try { 
      javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES"); 
      cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key); 
      byte[] raw = IOUtil.toByteArray(inputStream); 
      byte[] base64Decoded = Base64.decodeBase64(raw); 
      byte[] decryptedData = cipher.doFinal(base64Decoded); 
      outputStream.write(decryptedData); 
     } catch (InvalidKeyException e) { 
      e.printStackTrace(); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } catch (NoSuchPaddingException e) { 
      e.printStackTrace(); 
     } catch (IllegalBlockSizeException e) { 
      e.printStackTrace(); 
     } catch (BadPaddingException e) { 
      e.printStackTrace(); 
     } finally { 
      inputStream.close(); 
      outputStream.close(); 
     } 
    } 

    @Override 
    public void encrypt(InputStream inputStream, OutputStream outputStream) throws IOException { 
     try { 
      javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance("AES"); 
      cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key); 
      byte[] raw = IOUtil.toByteArray(inputStream); 
      byte[] encryptedData = cipher.doFinal(raw); 
      byte[] base64Encoded = Base64.encodeBase64(encryptedData); 
      outputStream.write(base64Encoded); 
     } catch (InvalidKeyException e) { 
      e.printStackTrace(); 
     } catch (NoSuchAlgorithmException e) { 
      e.printStackTrace(); 
     } catch (NoSuchPaddingException e) { 
      e.printStackTrace(); 
     } catch (IllegalBlockSizeException e) { 
      e.printStackTrace(); 
     } catch (BadPaddingException e) { 
      e.printStackTrace(); 
     } finally { 
      inputStream.close(); 
      outputStream.close(); 
     } 
    } 

} 

LOG

# this is log from encryption 
raw: 
    [97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122] 
encrypted: 
    [92, -104, -48, -10, 95, -3, -21, 46, 27, -60, -115, 85, 114, -95, -126, 108, 88, -105, 94, -84, 86, 86, -75, -83, -73, 24, -109, 86, -34, 83, -35, 106] 
base64Encoded: 
    [88, 74, 106, 81, 57, 108, 47, 57, 54, 121, 52, 98, 120, 73, 49, 86, 99, 113, 71, 67, 98, 70, 105, 88, 88, 113, 120, 87, 86, 114, 87, 116, 116, 120, 105, 84, 86, 116, 53, 84, 51, 87, 111, 61] 

# this is from decryption 
raw (this is the base64Encoded): 
    [88, 74, 106, 81, 57, 108, 47, 57, 54, 121, 52, 98, 120, 73, 49, 86, 99, 113, 71, 67, 98, 70, 105, 88, 88, 113, 120, 87, 86, 114, 87, 116, 116, 120, 105, 84, 86, 116, 53, 84, 51, 87, 111, 61] 
base64Decoded (this is the encrypted): 
    [92, -104, -48, -10, 95, -3, -21, 46, 27, -60, -115, 85, 114, -95, -126, 108, 88, -105, 94, -84, 86, 86, -75, -83, -73, 24, -109, 86, -34, 83, -35, 106] 
decrypted (this should be the raw from the encryption): 
    I don't know - the exception is thrown 
+0

添加一個重現此問題的主要方法,以便我們對其進行測試。 –

回答

1

嗯,你的加密代碼,似乎有點片狀入手:

byte[] raw = IOUtil.toByteArray(inputStream); 
byte[] encryptedData = cipher.doFinal(); 

cipher加密的數據怎麼樣?我懷疑你打算通過raw撥打doFinal電話。

我懷疑這是完整的問題,但它至少是一個起點。

EDIT爲後人:從評論來看,問題是不同的實例被用於加密和解密,因此不同的密鑰。

+0

我錯過了那個,謝謝。但它仍然會拋出同樣的異常... – user219882

+0

@Tom:你是否檢查過設法將正確的數據恢復到解密方法?例如,檢查'encryptedData'和'base64Decoded'的長度。 –

+0

我上面發佈了日誌。一切看起來都很好,我不知道問題出在哪裏...... – user219882