Intereting Posts
вывод неподписанного символа подписанного символа Объявление массива без наивысшего измерения getchar (), вызывающий только каждый раз Ограничивает ли `const T * ограничение` объект, на который указывает, не изменяется? Печать значения windows ввода в диалоговом окне в gtk c Пожалуйста, объясните вывод sizeof () Как печатать расширенные символы ASCII с 127 по 160 в программе C? MySQL C API: нужен пример для запуска БД в режиме * Встроенный * Печать шестнадцатеричного представления массива char Является ли стандартным для #if принимать неопределенные символические константы как 0? Проверьте, является ли символ ASCII использованием битмаски и битовых операторов в C Можно ли вызвать функцию C, учитывая ее имя как строку? С семафоров: sem_wait бросает необъяснимую ошибку Объявление массива Char и инициализация в C Создание связанного графика и проверка, имеет ли он эйлеровый цикл

Ошибка заполнения – при использовании AES Encryption в Java и расшифровке в C

У меня возникла проблема при расшифровке файла xl в коде rijndael ‘c‘ (файл был зашифрован на Java через JCE), и эта проблема происходит только для типов файлов excel, имеющих формулу. Оставшееся все шифрование / дешифрование типа файлов происходит должным образом.

(Если я дешифровать один и тот же файл в java, выход будет прекрасным.)

В то время как я сбрасывал файл, я вижу разницу между расшифровкой Java и расшифровкой файла «C».

od -c -b имя файла (файл расшифрован в C)

0034620 005 006 \0 \0 \0 \0 022 \0 022 \0 320 004 \0 \0 276 4 005 006 000 000 000 000 022 000 022 000 320 004 000 000 276 064 0034640 \0 \0 \0 \0 \f \f \f \f \f \f \f \f \f \f \f \f 000 000 000 000 014 014 014 014 014 014 014 014 014 014 014 014 0034660 

od -c -b имя файла (файл расшифрован в Java)

 0034620 005 006 \0 \0 \0 \0 022 \0 022 \0 320 004 \0 \0 276 4 005 006 000 000 000 000 022 000 022 000 320 004 000 000 276 064 0034640 \0 \0 \0 \0 000 000 000 000 0034644 

(выше – разница между сбрасываемыми файлами)

Следующий код java, который я использовал для шифрования файла.

 public class AES { /** * Turns array of bytes into string * * @param buf * Array of bytes to convert to hex string * @return Generated hex string */ public static void main(String[] args) throws Exception { File file = new File("testxls.xls"); byte[] lContents = new byte[(int) file.length()]; try { FileInputStream fileInputStream = new FileInputStream(file); fileInputStream.read(lContents); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } try { KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(256); // 192 and 256 bits may not be available // Generate the secret key specs. SecretKey skey = kgen.generateKey(); // byte[] raw = skey.getEncoded(); byte[] raw = "aabbccddeeffgghhaabbccddeeffgghh".getBytes(); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(lContents); cipher.init(Cipher.DECRYPT_MODE, skeySpec); byte[] original = cipher.doFinal(lContents); FileOutputStream f1 = new FileOutputStream("testxls_java.xls"); f1.write(original); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 

Я использовал следующий файл для расшифровки в ‘C’.

 #include  #include "rijndael.h" #define KEYBITS 256 #include  #include "rijndael.h" #define KEYBITS 256 int main(int argc, char **argv) { unsigned long rk[RKLENGTH(KEYBITS)]; unsigned char key[KEYLENGTH(KEYBITS)]; int i; int nrounds; char dummy[100] = "aabbccddeeffgghhaabbccddeeffgghh"; char *password; FILE *input,*output; password = dummy; for (i = 0; i < sizeof(key); i++) key[i] = *password != 0 ? *password++ : 0; input = fopen("doc_for_logu.xlsb", "rb"); if (input == NULL) { fputs("File read error", stderr); return 1; } output = fopen("ori_c_res.xlsb","w"); nrounds = rijndaelSetupDecrypt(rk, key, 256); while (1) { unsigned char plaintext[16]; unsigned char ciphertext[16]; int j; if (fread(ciphertext, sizeof(ciphertext), 1, input) != 1) break; rijndaelDecrypt(rk, nrounds, ciphertext, plaintext); fwrite(plaintext, sizeof(plaintext), 1, output); } fclose(input); fclose(output); } 

Чтобы удалить дополнение PKCS, добавляемое Java, стороне C необходимо прочитать значение последнего байта в последнем блоке decypted, а затем обрезать это количество байтов с конца дешифрованного streamа.

Это означает, что вы не можете выполнить свой fwrite до тех пор, пока не попытаетесь прочитать следующий блок (потому что вам нужно знать, является ли текущий блок последним или нет):

 unsigned char plaintext[16]; unsigned char ciphertext[16]; int last_block; last_block = (fread(ciphertext, sizeof(ciphertext), 1, input) != 1); while (!last_block) { size_t plaintext_size = sizeof plaintext; rijndaelDecrypt(rk, nrounds, ciphertext, plaintext); last_block = (fread(ciphertext, sizeof(ciphertext), 1, input) != 1); if (last_block) { /* Remove padding */ plaintext_size -= plaintext[(sizeof plaintext) - 1]; } if (plaintext_size) { fwrite(plaintext, plaintext_size, 1, output); } } 

Я изменил операцию чтения файла в файле ‘c’. Теперь все идет хорошо.

Спасибо за вашу поддержку. 🙂