2010-06-22 161 views
4

我嘗試解密最初使用Java中的Objective-C加密的數據。解密使用Objective-C與Java進行AES加密的數據

還有其他問題提到這一點,但他們真的很混亂,他們中的許多都還沒有解決,因此我會張貼自己的。

這是對數據加密的代碼:

- (int) encryptWithKey: (NSString *) key 
    { 
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise 
    char * keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused) 
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) 

    // fetch key data 
    [key getCString: keyPtr maxLength: sizeof(keyPtr) encoding: NSUTF8StringEncoding]; 

    // encrypts in-place, since this is a mutable data object 
    size_t numBytesEncrypted = 0; 
    CCCryptorStatus result = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, 
            keyPtr, kCCKeySizeAES128, 
            NULL /* initialization vector (optional) */, 
            [self mutableBytes], [self length], /* input */ 
            [self mutableBytes], [self length]+32, /* output */ 
            &numBytesEncrypted); 
    return numBytesEncrypted; 
} 

我執行此功能,並將所得數據刻錄到光盤,此代碼寫:

NSString* strTest = @"Hallo Welt!"; 
NSLog(@"strTest = %@", strTest); 

NSMutableData *protectedData = [NSMutableData dataWithData:[strTest dataUsingEncoding:NSUTF8StringEncoding]]; 

int laenge = [protectedData encryptWithKey:@"keykeykeykeykeykeykeykey"]; 

NSData* dataOutput = [[NSData alloc] initWithBytes:[protectedData bytes] length:laenge]; 


[dataOutput writeToFile:@"/encryptedFileObjC" atomically:YES]; 

在Java中我使用此代碼試圖達到相同的行爲:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
String keyString = "keykeykeykeykeykeykeykey"; 
byte[] keyBytes = keyString.getBytes("UTF-8"); 

cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(keyBytes, "AES"), 
     new IvParameterSpec(new byte[16])); 
byte[] resultBytes = cipher.doFinal("Hallo Welt!".getBytes("UTF8")); 

FileOutputStream out = 
     new FileOutputStream(new File("encryptedFileJava")); 
out.write(resultBytes); 
out.close(); 

如果我現在嘗試解密文件是e通過Objective-C加密我得到了一個不好的填充異常。如果我用加密的內容打開這兩個文件,它們是不同的:

Hallo Welt!用Java加密:96 C5 CB 51 39 B5 27 FB B3 93 BF 92 18 BB 16 9B
Hallo Welt!使用ObjC加密:A3 61 32 8E A5 E6 66 E0 41 64 89 25 62 D3 21 16

文件內容不應該相同嗎?我想我沒有在兩種語言中得到相同算法的所有參數。

我需要修改Java代碼以獲得與Objective-C代碼相同的結果,以便能夠解密用Objective-C加密的一些數據。

+0

我很驚訝Java代碼可以運行,因爲keyBytes數組只有長度15,而不是有效的AES密鑰長度。 – 2010-06-22 11:07:35

+0

密鑰長度爲什麼是15?我假設長度是24字節,我對加密非常陌生,所以如果我有一個基本的誤解,請糾正我。 – Janusz 2010-06-22 12:10:23

+0

@Janusz你可以幫我拿這個加密/解密的示例代碼,我的電子郵件ID是 - [email protected]。我面臨同樣的問題。謝謝。 – 2013-06-28 08:15:08

回答

2
  1. 我不會假設CCCrypt支持使用相同的數組輸入和輸出。嘗試使用兩個不同的數組。
  2. 你必須自己調整輸出數組的大小(在調用之後numBytesEncrypted應該等於16)。
  3. 據我所見,一個空IV信號使用ECB加密而不是CBC。只要你的輸入小於15字節,它應該沒有什麼區別,但它仍然是你應該修復的東西。

編輯:另一個問題:

  • 您正在使用24字節密鑰。AES-128需要128位= 16字節密鑰,AES-192需要192位= 24字節密鑰,AES-256需要256位= 32字節密鑰。您明確地將AES-128指示爲CCCrypt,這意味着它將忽略密鑰的最後8個字節。您只是將AES指示爲Java,這意味着它會根據密鑰大小來決定使用哪種AES變體。由於您提供的是24字節密鑰,因此它使用AES-192。修復它,使兩端使用相同的算法,你應該是好的。
  • +0

    你是對的我編輯了我關於NSDATA管理的問題。現在我得到正確的長度,但仍然是一個完全不同的加密 – Janusz 2010-06-22 13:15:49

    +0

    也使用Java中沒有IV和PKCS5padding的ECB在加密中給出了相同的結果,沒有任何附近的ObjC結果。 – Janusz 2010-06-22 13:18:15

    +0

    謝謝,如果我只使用密鑰的前16個字節,它就像一個魅力。 – Janusz 2010-06-23 06:57:17

    1

    您可能有一堆問題。

    在做任何加密/解密,你需要確保:

    • 字符串編碼是相同的(你使用兩個UTF8,這就是好)
    • 填補方案是相同的(你PKCS5上一個和PKCS7另一方面)
    • 初始化向量是相同的(你對其他的一個空和空字節)

    當然..和所述加密方案是相同的。混淆你的加密似乎使用AES128,雖然評論討論使用AES256。不知道什麼Java版本正在使用

    +0

    我的填充問題是它似乎在java中沒有可用的pkcs5padding。其他一些網頁建議使用pkcs5,因爲它幾乎相同。 – Janusz 2010-06-22 10:57:29

    +1

    「PKCS#5填充」和「PKCS#7填充」是同義詞。 – 2010-06-22 12:51:53

    1

    這可能無助於你的問題,但它是錯的呢:

    char * keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused) 
    

    定義kCCKeySizeAES128 + 1個指針,不kCCKeySizeAES128 + 1個的字節數組。碰巧,因爲你得到的緩衝區比你需要的大四倍或八倍,這取決於你是在編譯32位還是64位。

    +0

    我不能做任何與objc代碼的數據已被加密 – Janusz 2010-06-22 12:56:28