iOS5和iOS6的CCCrypt区别

Posted

技术标签:

【中文标题】iOS5和iOS6的CCCrypt区别【英文标题】:CCCrypt difference between iOS5 and iOS6 【发布时间】:2012-09-17 18:10:36 【问题描述】:

我有一个使用CCCrypt() 的解密/加密方法,它在ios5 上运行得非常好。现在我正在使用 iOS6 SDK 并且从未更改过我的代码,但似乎有些东西坏了。我仍然可以使用密钥加密字符串并对其进行解密,但如果我使用另一个密钥解密相同的字符串,则从 CCCrypt() 返回的 CCCryptStatus 仍然是 0(kCCSuccess) - 即使解密失败,因为在那之后我的 NSData 没有填满。在 iOS5 上,我收到了我可以处理的错误消息 -4303。有什么想法现在有什么问题吗?

我的代码:

char keyPtr[kCCKeySizeAES256+1]; 
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

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

if (encryptOrDecrypt == kCCDecrypt)

    data = [GTMBase64 decodeData:data];


NSUInteger dataLength = [data length];

size_t bufferSize = dataLength + kCCBlockSizeAES128;

void *buffer = malloc(bufferSize);

size_t numBytesDecrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(encryptOrDecrypt,
                                      kCCAlgorithmAES128,
                                      kCCOptionPKCS7Padding,
                                      keyPtr,
                                      kCCKeySizeAES256,
                                      NULL ,
                                      [data bytes], dataLength, 
                                      buffer,       bufferSize, 
                                      &numBytesDecrypted);

if (cryptStatus != kCCSuccess)
    // do something, but cryptStatus is always 0!

编辑: 在 iPad Simulator 5 上对其进行了测试。当我使用另一个密钥进行解密时,我收到的状态是 -4303。仅在 ios6 中返回的状态为 0。

【问题讨论】:

我似乎也有类似的问题。解密在 ios5 中工作,但在 ios6 中失败。加密是使用 php 中的 mcrypt_encrypt 完成的。我也获得了成功状态,但decryptedBytes 为0。有什么想法和解决方案吗? 我仍在寻找解决方案。在苹果开发者论坛中有一个名为 CommonCrypto 问题的线程。有些人讨论了类似的问题,但直到现在才解决这个问题。 【参考方案1】:

我不是加密专家,但我遇到了同样的问题并想出了一个解决方法,也许在有人找到真正的解决方案之前会很好。

我所做的只是确定哪个 iOS 正在运行,对于 6+,我将 CCCrypt 调用更改为无填充(0 表示无填充,1 是 kCCOptionPKCS7Padding 的枚举)

float version = [[UIDevice currentDevice].systemVersion floatValue];
if (version >= 6)

    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 0,
                                          keyPtr, kCCKeySizeAES128,
                                          ivPtr,
                                          [self bytes], dataLength,
                                          buffer, bufferSize, 
                                          &numBytesDecrypted );


    if( cryptStatus == kCCSuccess )
    
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    

    free( buffer ); 
    return nil;

else

    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, 1,
                                          keyPtr, kCCKeySizeAES128,
                                          ivPtr,
                                          [self bytes], dataLength,
                                          buffer, bufferSize, 
                                          &numBytesDecrypted );
    if( cryptStatus == kCCSuccess )
    
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    

    free( buffer );
    return nil;

【讨论】:

我还没有测试过,但它真的只是iOS6上改变的填充吗?在开发者论坛上有人告诉我,我的代码也不适用于 iOS5。但我不知道为什么......我想我错过的是一个事实,即不可能知道用另一个密钥解密是否失败 - 在 iOS5 上,如果用另一个密钥解密失败,我每次都会收到 -4303 错误。但这可能是幸运的......所以我真正的问题可能是整个想法,而不是 iOS6 的代码。 我们遇到了一些问题,它在加密和/或解密的末尾添加了尾随字节。设置 0 填充解决了这个问题。【参考方案2】:

有一个苹果developer forum thread 讨论这个问题,它有很多关于这个话题的信息。似乎填充选项对许多人来说是一个问题。评论 #11 是开始讨论解决方案的地方。

【讨论】:

以上是关于iOS5和iOS6的CCCrypt区别的主要内容,如果未能解决你的问题,请参考以下文章

iOS6 和 iOS5 中 UIImage Orientation 的不同行为

IOS 5 和 IOS6 有不同的界面定位结果

当我们在 ios5.1、ios6 等其他操作系统版本中拥有应用程序时,如何在 ios5 模拟器中启动应用程序?

iOS7发布后,iOS5或iOS6的应用是不是还可以提交到App Store

网站在 iOS6 中正常呈现,但在 iOS5 iPad 模拟器中翻倍

setDelegateQueue 在 iOS5 上不工作,但在 iOS6 上工作正常