2009-12-18 70 views
3

在Java和解密使用AES加密時,我有一個問題,同時解密的Rijndael算法的C語言代碼(該文件得到通過JCE加密在Java中)的XL文件,而這個問題只發生爲Excel具有公式的文件類型。剩餘的所有文件類型加密/解密正常發生。填充錯誤 - 在C

(如果我在Java解密同一文件的輸出來了細。)

雖然我轉儲文件I可以看到的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); 
    } 
+0

似乎很奇怪,這個問題會涉及到的內容,而不是長度。 AES具有128個比特的塊大小,因此它需要一個長的輸入。也許Java是使用由默認的填充方案,其C未被除去。 – TheManWithNoName 2009-12-18 10:38:22

+0

糾正:該長度 – TheManWithNoName 2009-12-18 10:39:03

回答

1

爲了去除Java已加入PKCS填充,C側需要讀取在最後decypted塊中的最後一個字節的值,然後修剪,從解密流的末尾的字節數。

這意味着,你不能做你的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); 
    } 
} 
0

我修改了'c'文件中的文件讀取操作。現在它會好起來的。

感謝您的支持。 :-)

+0

的倍數,這應該是一個評論 – Janusz 2010-06-22 12:48:28