我在用 rijndael 'c' 代码解密 xl 文件时遇到问题(该文件通过 JCE 在 Java 中加密),并且此问题仅发生在具有公式的 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);
}