2016-12-19 74 views
6

我目前使用的iOS上的三重DES解密如下:三重DES解密iOS中

NSString* plainText = @"My Text"; 
    NSString* keyText = @"cf6f1ed3bf0a156e"; 

    NSData *plainData = [plainText dataUsingEncoding:NSUTF8StringEncoding]; 
    NSData *keyData = [keyText dataUsingEncoding:NSUTF8StringEncoding]; 

    size_t bufferSize = plainData.length + kCCBlockSize3DES; 
    NSMutableData *cypherData = [NSMutableData dataWithLength:bufferSize]; 
    size_t movedBytes = 0; 

    CCCryptorStatus ccStatus; 
    ccStatus = CCCrypt(kCCDecrypt, 
      kCCAlgorithm3DES, 
      kCCOptionECBMode, 
      keyData.bytes, 
      kCCBlockSize3DES, 
      NULL, 
      plainData.bytes, 
      plainData.length, 
      cypherData.mutableBytes, 
      cypherData.length, 
      &movedBytes); 

    cypherData.length = movedBytes; 

    if(ccStatus == kCCSuccess) { 
     NSLog(@"Data: %@",cypherData); 
     NSLog(@"Data encoded string: %@",[NSString stringWithUTF8String:[cypherData bytes]]); 
     NSLog(@"Data encoded: %@",[[NSString alloc] initWithData:cypherData encoding:NSUTF8StringEncoding]); 
    } else { 
     NSLog(@"Failed DES decrypt ..."); 
     return nil; 
    } 

不過,我不斷收到在控制檯以下:

數據: 數據編碼的字符串:(null) 數據編碼:(null)

有關爲何發生這種情況的任何想法?任何人都可以看到任何可能的問題與此代碼?

回答

2

更改失敗消息:

NSLog(@"Failed DES decrypt, status: %d", ccStatus); 

你會看到一個-4300狀態,並期待,最多在CommonCryptoError.h發現:如果你
kCCParamError = -4300
@constant kCCParamError Illegal parameter value.

狀態錯誤可以成爲你的朋友不要忽視他們。

  1. 您正在指定3DES,其密鑰長度應爲24個字節,您提供的是16個字節。您可能最好更改爲kCCAlgorithmDESkCCBlockSizeDES(請參閱下一點)。但密鑰可能是十六進制編碼,需要解碼爲8字節。

  2. 在通話中,第5個參數是size_t keyLength,但是您提供的是8字節的kCCBlockSize3DES。密鑰和塊大小不一定相同。

  3. 沒有填充是默認值,這意味着,要加密的數據必須確切多個塊大小(8字節)的。將另一個字節添加到輸入數據或指定kCCOptionPKCS7Padding作爲選項。

  4. 通常,不可能直接在字符串中表示加密結果,特別是不能表示UTF-8表示 - 存在不可顯示的字節值。出於這個原因,如果你需要一個字符串編碼,通常使用Base64或十六進制。

注:有一種可能性,關鍵是需要3DES 16字節和兩個鍵,在這種情況下,複製和第8個字節追加到關鍵要提出的是一個24字節3DES密鑰。你需要掌握算法,關鍵和選項。

此示例代碼的作品,但既不是最佳也不是安全的,但出發點,讓你去:

可以通過提供一個24字節的密鑰和改變kCCAlgorithmDESkCCAlgorithm3DESkCCKeySizeDESkCCKeySize3DES

改變這3DES
NSString* plainText = @"My Text-"; 
NSString* keyText = @"cf6f1ed3"; 

NSData *plainData = [plainText dataUsingEncoding:NSUTF8StringEncoding]; 
NSData *keyData = [keyText dataUsingEncoding:NSUTF8StringEncoding]; 

size_t bufferSize = plainData.length + kCCBlockSizeDES; 
NSMutableData *cypherData = [NSMutableData dataWithLength:bufferSize]; 
size_t movedBytes = 0; 

CCCryptorStatus ccStatus; 
ccStatus = CCCrypt(kCCDecrypt, 
        kCCAlgorithmDES, 
        kCCOptionECBMode, 
        keyData.bytes, 
        kCCKeySizeDES, 
        NULL, 
        plainData.bytes, 
        plainData.length, 
        cypherData.mutableBytes, 
        cypherData.length, 
        &movedBytes); 

cypherData.length = movedBytes; 

if(ccStatus == kCCSuccess) { 
    NSLog(@"Data: %@"encoded,cypherData); 
} else { 
    NSLog(@"Failed DES decrypt, status: %d", ccStatus); 
} 

但出於安全考慮,如果可能的話使用AES,如果可能的話使用RNCryptor,它會照顧所有討厭但重要的細節。

+0

從來沒有想過鑰匙是一個問題。謝謝您的幫助 – user481610

3

您的密鑰長度爲16個字節。 3DES需要一個長度爲24個字節的密鑰(謝謝Zaph糾正;也注意到你只讀了8個字節)。這可能不會導致這個錯誤,但意味着關鍵不是你認爲的那樣。

字符串中的一系列十六進制數字只是UTF-8值。 「00」不是0x00,0x00。它是0x30,0x30。

你在這裏得到(null)原因是這樣的:

NSLog(@"Data encoded string: %@",[NSString stringWithUTF8String:[cypherData bytes]]); 

加密輸出是不太可能成爲一個合法的UTF-8字符串。如果要將隨機數據編碼爲字符串,則需要使用十六進制編碼或Base64編碼等編碼。 Base64內置,您可以使用[NSData base64EncodedStringWithOptions:]對其進行編碼。