Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
填充错误-在Java中使用AES加密而在C中使用解密时_Java_C_Encryption - Fatal编程技术网

填充错误-在Java中使用AES加密而在C中使用解密时

填充错误-在Java中使用AES加密而在C中使用解密时,java,c,encryption,Java,C,Encryption,我在用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

我在用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 
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
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  \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 
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);  
    }
#包括
#包括“rijndael.h”
#定义密钥位256
#包括
#包括“rijndael.h”
#定义密钥位256
int main(int argc,字符**argv)
{  
无符号长rk[RKLENGTH(键位)];
无符号字符键[KEYLENGTH(KEYBITS)];
int i;
整数;
字符虚拟[100]=“aabbccddeffgghaabbccddeffgghh”;
字符*密码;
文件*输入,*输出;
密码=虚拟;
对于(i=0;i
为了删除Java正在添加的PKCS填充,C端需要读取最后一个解密块中最后一个字节的值,然后从解密流的末尾修剪这么多字节

这意味着您在尝试读取下一个块之前(因为您需要知道当前块是否是最后一个块),无法执行
fwrite


我修改了“c”文件中的文件读取操作。现在好了


感谢您的支持。:-)

奇怪的是,问题与内容有关,而与长度无关。AES的块大小为128位,因此需要输入该长度。也许java默认使用的是C没有删除的填充方案。更正:该长度的倍数