2016-12-19 75 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:]对其进行编码。