2016-09-20 154 views
1

我正在開發Android應用程序,我正在使用Android的密碼類對進行解密。Cipher.dofinal出現內存不足錯誤()

代碼:

private byte[] decrypt_chunk(byte[] data, ByteString chunk_encryption_key) { 
     SecretKeySpec skeySpec = new SecretKeySpec(chunk_encryption_key.toByteArray(), 1, 16, "AES"); 
     Cipher cipher; 
     byte[] decrypted = new byte[0]; 
     try { 
      cipher = Cipher.getInstance("AES/CFB/NoPadding"); 

      cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(getIV(0))); 

      decrypted = cipher.doFinal(data); 

     } catch (NoSuchAlgorithmException | NoSuchPaddingException e) { 
      e.printStackTrace(); 
     } catch (InvalidKeyException e) { 
      e.printStackTrace(); 
     } catch (InvalidAlgorithmParameterException e) { 
      e.printStackTrace(); 
     } catch (ShortBufferException e) { 
      e.printStackTrace(); 
     } 

     return decrypted; 
    } 

我得到「內存不足」錯誤,而解密大文件。

我有以下問題:

  1. 在當前的代碼是什麼chanegs可以修復OOM錯誤

  2. Cipher.update()可以幫助解決這個問題?如果是的話,如何實施呢?

謝謝。

+0

如何加載數據? –

+0

我正在從在線服務器讀取數據並將其存儲在byte []中。 –

+0

您無法一次加載整個文件。您需要一次加載塊。 –

回答

2

使用Cipher.update()方法是一種可能的方法。

但在你的情況下,我建議你使用CipherOutputStream來代替。我假設你有一個用於從服務器獲取數據的InputStream和一個用於將數據保存到文件中的FileOutputStream。

使用CipherOutputStream是非常簡單的,只是「總結爲」繞FileOutputStream中:

FileOutputStream fout = ... 
CipherOutputStream cout = new CipherOutputStream(fout, cipher); 

現在繼續使用cout而不是fout和你寫進去一切都將被自動加密。

+0

謝謝你的回答。但是我需要在從服務器讀取字節的同時執行一些操作,因此我將數據存儲爲byte []。 –

+0

或者您使用'ChipherInputStream'代替(讀取時加密/解密)。它以相同的方式工作,但包裝一個InputStream,就像從Web加載文件時獲得的那樣。 – Robert