У меня проблема при расшифровке файла 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 <stdio.h>
#include "rijndael.h"
#define KEYBITS 256
#include <stdio.h>
#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);
}