我正在使用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,并直接将字符串写入文件而不是字节。不幸的是,我仍然得到错误。但是,从读取行看到的结果字符串中的seem似乎较少。
答案 0 :(得分:3)
看起来问题出在你的fileReader.readLine()上 - 你正在写一个字节流到一个文件,然后把它作为一个字符串读回来。相反,你应该读入一个字节流,例如refer to this question,或者使用Base64 Encoding将字节数组转换为字符串,将其写入文件,从文件中读取,然后将其转换回字节数组。
答案 1 :(得分:1)
我相信你错误地使用了一个Reader,它是一个被定义为在你真正想要严格按字节处理时读取字符的对象。这很可能不是你的整个问题,但如果你要写字节,你应该读取字节而不是字符。