2014-09-01 61 views
2

我已經以下教程「How do I encrypt and decrypt files using DES?」爲一種簡單的文件加密添加到現有的Android 4+應用程序。複製字節CipherOutputStream(或反之亦然)非常慢

一切工作正常,除了加密和解密是非常,非常緩慢。

以下兩種方法都非常完整教程:

public static void encryptOrDecrypt(String key, int mode, InputStream is, OutputStream os) throws Throwable { 
    DESKeySpec dks = new DESKeySpec(key.getBytes()); 
    SecretKeyFactory skf = SecretKeyFactory.getInstance("DES"); 
    SecretKey desKey = skf.generateSecret(dks); 
    Cipher cipher = Cipher.getInstance("DES"); // DES/ECB/PKCS5Padding for SunJCE 

    if (mode == Cipher.ENCRYPT_MODE) { 
     cipher.init(Cipher.ENCRYPT_MODE, desKey); 
     CipherInputStream cis = new CipherInputStream(is, cipher); 
     doCopy(cis, os); 
    } else if (mode == Cipher.DECRYPT_MODE) { 
     cipher.init(Cipher.DECRYPT_MODE, desKey); 
     CipherOutputStream cos = new CipherOutputStream(os, cipher); 
     doCopy(is, cos); 
    } 
} 

public static void doCopy(InputStream is, OutputStream os) throws IOException { 
    byte[] bytes = new byte[64]; 
    int numBytes; 

    // Why is this taking so long? 
    while ((numBytes = is.read(bytes)) != -1) { 
     os.write(bytes, 0, numBytes); 
    } 

    os.flush(); 
    os.close(); 
    is.close(); 
} 

相當簡單和基本的,但它需要約20-30秒,DE /加密1 MB的文件。詳細地說,它是在兩個流之間複製字節的while循環非常慢。

字節[]的大小更改爲65536像一個更大的價值,同時讀取多個字節不會改變任何東西。我認爲一次讀更多的字節會加快這個過程,但事實並非如此。

在沒有加密的「普通」流之間複製數據並不需要很長時間。這真的是加密這是昂貴的?我在其他平臺上使用過類似的加密技術,這種延遲從來都不是問題。

本教程使用DES,但將算法更改爲不同的內容,例如AES也不會改變任何東西。

任何想法,我可以加快這一點?

+0

如果你刪除加密並只使用'doCopy(is,os)''會發生什麼? – CodesInChaos 2014-09-01 14:23:39

+0

如果我使用doCopy(is,os)''is'是一個簡單的(無密碼)'FileInputStream'和'os'簡單的(無密碼)'FileOutputStream',我當前測試文件的完整副本大約需要150ms 。如果包含CipherStream,則使用相同文件的操作最多需要15000ms。因此,顯然延遲是由CipherStream引起的。但爲什麼?加密/解密需要時間,但這很多? – 2014-09-01 14:57:18

+0

即使在移動CPU上,正確的加密實現應該至少比此快100倍。 – CodesInChaos 2014-09-01 15:00:14

回答

2

我進行了一些實驗,我的谷歌Nexus專用的LG 5使用基本上你的代碼運行的是Android 4.4.4和加密的1000000(一百萬)個字節的文件,閱讀,並從/ SD卡文件系統寫入/。

no crypt 1421 ms 
AES ECB mode 2577 ms 
DES ECB 3214 

接下來,我修改你的代碼稍微使用BufferedInputStreamBufferedOutputStream

no crypt 88 ms 
AES ECB mode 855 ms 
DES ECB mode 1419 MS 

這表明,定時對緩存敏感,而AES比DES更快。

提供程序名稱是「AndroidOpenSSL」

+0

非常感謝您的回答。我在真實的設備上運行了代碼,但調試器已連接。這似乎會減緩這一進程。如果應用程序直接啓動(沒有日食),則解密/加密速度將與預期的一樣快。我不明白爲什麼調試器會減慢這個過程的速度,但解決這個問題很好:-)使用BufferedStreams可以提供一些額外的速度! – 2014-09-02 06:21:48

1

你可能有一個問題,一些工藝堵輸入文件。要測試問題是否是這樣的:計算應讀取的文件的最後部分以及您將讀取的完整緩衝區的數量。用for循環替換while,如果文件大小/緩衝區大小有餘,則添加額外的讀寫。