2013-04-08 105 views
0

我用Java的加密庫工作,並得到一個IllegalBlockSizeException.加密/解密,得到IllegalBlockSizeException

目前我試圖提取XML文件格式的數據庫內容。在數據轉儲過程中,我正在創建一個清單文件,其中包含使用數據庫中定義的鍵進行解密的字符串。

稍後,當XML文件的內容被加載到另一個數據庫中時,它將從該數據庫獲取密鑰並使用它來解密清單。如果解密後的清單與原始內容不匹配,則意味着源數據庫和目標數據庫中的加密密鑰不匹配,並且會通知用戶這一點。

以下是代碼。 EncryptionEngine對象是一個使用Java加密庫來抽象出很多加密細節的單例。假設它工作正常,因爲它是相當古老和成熟的代碼。

這是我所做的一堂課。首先,我們有這些數據成員:

private final String encryptedManifestContents; 
private final static String DECRYPTED_MANIFEST_CONTENTS = "This file contains the encrypted string for validating data in the dump and load process"; 
final static String ENCRYPTED_MANIFEST_FILENAME = "manifest.bin"; 

首先是加密過程。該字符串像下面加密:

final EncryptionEngine encryptionEngine = EncryptionEngine.getInstance(); 
encryptedManifestContents = encryptionEngine.symmetricEncrypt(DECRYPTED_MANIFEST_CONTENTS); // The contents get converted to bytes via getBytes("UTF-8") 

然後寫入清單文件(目標僅僅是保持該文件的路徑作爲一個字符串變量):

EncryptedManifestUtil encryptedManifestUtil = new EncryptedManifestUtil(); // The class I've created. The constructor is the code above, which just initialized the EncryptionEngine and encrypted the manifest string. 
manifestOut = new FileOutputStream(destination + "/" + ENCRYPTED_MANIFEST_FILENAME); 
manifestOut.write(encryptedManifestUtil.encryptedManifestContents.getBytes("UTF-8")); 

此時,加密處理已經完成了。我們已經採取了一個字符串,對其進行了加密,然後按照該順序將內容寫入文件。現在,當有人加載數據,解密過程開始:

BufferedReader fileReader = new BufferedReader(new FileReader(filename)); // Filename is the manifest's file name and location 
final EncryptionEngine encryptionEngine = EncryptionEngine.getInstance(); 
String decryptedManifest = encryptionEngine.decryptString(fileReader.readLine().getBytes("UTF-8")); // This is a symmetric decrypt 

當解密發生,這引發此異常:

Caused by: javax.crypto.IllegalBlockSizeException: last block incomplete in decryption 
    at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source) 
    at javax.crypto.Cipher.doFinal(DashoA13*..) 

它似乎正確地讀寫的文件,但內容對我來說都是胡言亂語。 fileReader.readLine()的結果是:

9�Y�������䖷�߾��=Ă��� s7Cx�t�b��_-(�b��LFA���}�6�f����Ps�n�����ʢ�@�� �%��%�5P�p 

感謝您的幫助。

編輯:所以我改變了我寫入文件的方式。

召回這一行:

encryptedManifestContents = encryptionEngine.symmetricEncrypt(DECRYPTED_MANIFEST_CONTENTS); 

的加密首先獲取從所輸入的字符串的字節數,進行解密,然後通過首先改變字節回字符串它編碼到基座64個字節。然後它將基本的64字節數組轉換回字符串。

考慮到這一點,我改變了文件寫入到PrintWriter,而不是一個FileOutputStream並直接寫入字符串的文件,而不是字節。不幸的是,我仍然遇到了這個錯誤。然而,從讀取行中得到的字符串中似乎少了1/3。

+0

爲什麼在寫入之前在加密的字符串上使用'getBytes()'? – 2013-04-08 18:54:08

+0

您向我們展示了除相關代碼之外的所有內容:實際加密和解密的代碼。 – 2013-04-08 18:58:33

+0

我希望問題在於我如何讀取/寫入文件。我無法直接向您顯示加密代碼,因爲它屬於我的公司。如有必要,我可以粗略地概述一下。 – Slims 2013-04-08 19:08:33

回答

3

它看起來像問題是與您的fileReader.readLine() - 你正在寫一個字節流文件,然後閱讀它回爲一個字符串。相反,您應該讀取一個字節流,例如refer to this question,或者使用Base64 Encoding將字節數組轉換爲字符串,將其寫入文件,從文件讀取數據並將其轉換回字節數組。

+0

看到我的編輯,試圖做到這一點,但仍然無法工作 – Slims 2013-04-08 19:14:23

+0

嘗試解密加密的字節數組而不寫入或讀取文件,以確定是否問題在於你的加密/解密,或者如果問題出在你的IO上 – 2013-04-08 19:17:37

+0

這實際上起作用了,我忘了重新加載數據,所以我使用的是舊的清單寫錯了方式:) – Slims 2013-04-08 19:29:12

1

我相信你是正確使用閱讀器,其被定義爲讀取字符當你真正想成爲以字節爲單位嚴格處理的對象。這很可能不是你的問題的全部,但如果你正在寫字節,你應該讀字節而不是字符。