0

我正在使用 Java 的加密库并获得一个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,并直接将字符串写入文件而不是字节。不幸的是,我仍然收到错误消息。但是,读取行的结果字符串中的 � 似乎较少。

4

2 回答 2

3

看起来问题出在您的 fileReader.readLine() 上-您正在将字节流写入文件,然后将其作为字符串读回。相反,您应该读入字节流,例如参考这个问题,或者使用Base64 编码将字节数组转换为字符串,将其写入文件,从文件中读取,然后将其转换回字节大批。

于 2013-04-08T19:00:00.620 回答
1

我相信您错误地使用了 Reader,它是一个定义为读取字符的对象,而您实际上想要严格以字节为单位进行处理。这很可能不是您问题的全部,但如果您正在写入字节,您应该读取字节而不是字符。

于 2013-04-08T19:02:49.777 回答