2013-04-08 103 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

我相信你是正确使用阅读器,其被定义为读取字符当你真正想成为以字节为单位严格处理的对象。这很可能不是你的问题的全部,但如果你正在写字节,你应该读字节而不是字符。