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

Спасибо за помощь.

EDIT: Я изменил способ записи в файл.

Напомним, эта линия:

encryptedManifestContents = encryptionEngine.symmetricEncrypt(DECRYPTED_MANIFEST_CONTENTS); 

Шифровать первым получает байты из введенной строки, а затем расшифровывает, затем изменяет байты обратно в строку, сначала кодирующий его к основанию 64 байта. Затем он преобразует базовый массив из 64 байтов обратно в строку.

Имея это в виду, я сменил автора файла на PrintWriter вместо FileOutputStream и напрямую записал строку в файл вместо байтов. К сожалению, я до сих пор получаю ошибку. Однако, как представляется, меньше меньше в полученной строке из строки чтения.

+0

Зачем использовать 'getBytes()' в зашифрованной строке перед записью? –

+0

Вы показали нам все, кроме соответствующего кода: тот, который фактически шифрует и расшифровывает. –

+0

Я надеюсь, что проблема заключается в том, как я читаю/записываю файл. Я не могу прямо показать вам код для шифрования, поскольку он принадлежит моей компании. При необходимости я могу сделать грубую схему. – Slims

ответ

3

Похоже, проблема в файле fileReader.readLine() - вы пишете поток байтов в файл, а затем читаете его в виде строки. Вместо этого вы должны либо читать в байтовом потоке, например.refer to this question, либо использовать Base64 Encoding, чтобы преобразовать массив байтов в строку, записать его в файл, прочитать его из файла и преобразовать обратно в массив байтов.

+0

См. мое редактирование, попытался сделать это и все еще не сработал. – Slims

+0

Попробуйте расшифровать зашифрованный массив байтов, не записывая его или не считывая его из файла, чтобы определить, проблема связана с вашим шифрованием/расшифровкой или если проблема связана с вашим IO. –

+0

Это действительно сработало. Я забыл перезагрузить данные, поэтому я использовал старый манифест, написанный неправильным способом :) – Slims

1

Я считаю, что вы неправильно используете Reader, который является объектом, определенным для чтения символов, когда вы действительно хотите строго работать в байтах. Скорее всего, это не полностью ваша проблема, но если вы пишете байты, вы должны читать байты, а не символы.

Смежные вопросы