【问题标题】:AES Decryption has different behavior in iOS 7 than iOS 8/9AES 解密在 iOS 7 中的行为与 iOS 8/9 不同
【发布时间】:2015-08-06 04:27:51
【问题描述】:

以下方法在 iOS 7 上运行时返回的结果与在 iOS 8/9 上运行时不同。

+ (NSData *)decryptData:(NSData *)data key:(NSData *)key iv:(NSData *)iv;
{
  NSData *result = nil;

  // setup key
  unsigned char cKey[FBENCRYPT_KEY_SIZE];
  bzero(cKey, sizeof(cKey));
  [key getBytes:cKey length:FBENCRYPT_KEY_SIZE];

  // setup iv
  char cIv[FBENCRYPT_BLOCK_SIZE];
  bzero(cIv, FBENCRYPT_BLOCK_SIZE);
  if (iv) {
    [iv getBytes:cIv length:FBENCRYPT_BLOCK_SIZE];
  }

  // setup output buffer
  size_t bufferSize = [data length] + FBENCRYPT_BLOCK_SIZE;
  void *buffer = malloc(bufferSize);

  // do decrypt
  size_t decryptedSize = 0;
  CCCryptorStatus cryptStatus =
      CCCrypt(kCCDecrypt, FBENCRYPT_ALGORITHM, kCCOptionPKCS7Padding, cKey,
              FBENCRYPT_KEY_SIZE, cIv, [data bytes], [data length], buffer,
              bufferSize, &decryptedSize);

  if (cryptStatus == kCCSuccess) {
    result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
  } else {
    free(buffer);
    NSLog(@"[ERROR] failed to decrypt| CCCryptoStatus: %d", cryptStatus);
  }

  return result;
}

加密适用于 iOS 7/8/9。但在 iOS 7 上解密结果为零。

decryptedSize 执行后为 0。 buffer 元素保持为 0。

有些定义是

#define FBENCRYPT_ALGORITHM kCCAlgorithmAES128
#define FBENCRYPT_BLOCK_SIZE kCCBlockSizeAES128
#define FBENCRYPT_KEY_SIZE kCCKeySizeAES256

我已阅读关于 SO 的类似 CCCrypt() 问题的答案。尝试了以下方法:

  1. cKey 长度增加1
  2. cKey 长度增加到FBENCRYPT_KEY_SIZE * 2 + 1
  3. cKey 的第一个字节设置为0(有人说iOS 6 在从NSString 获取关键字节时会这样做)

以上都不起作用。


当方法被调用时,我返回了一些示例数据。

传递给decryptData的三个参数是:

  • 数据:ea1e6896 b5731f40 1d560a18 f0729fa6
  • 密钥:17c76e90 9a6fef8d b1fd45fa 2de18db0 d2236264 db6c8a60 125599ec 2dfb5614,AES256 为 256 位
  • iv:41463531 38453234 44333835 42463636,16字节,与块大小相同

预期结果(和 iOS8/9 上的实际结果)是248e51af 66bf85d3 00003ab6 fe3c0000

【问题讨论】:

  • 我提出了一个类似的问题,在 iOS 7 下不是 nil 结果,而是截​​断纯文本:stackoverflow.com/questions/31850550/…
  • 以十六进制形式为数据(未加密和加密)、密钥和iv提供样本输入。感兴趣的是密钥和iv的长度,它们应该分别是密钥长度和块大小。请注意,在 CCCrypt 的某些早期版本中,如果填充不正确,则会返回错误,这已更改为不产生错误,因为这是一个安全漏洞。
  • 数据如何加密、平台、语言和库/功能。特别是加密功能是否使用 PKCS#7(或 PKCS#5)填充?注意:不要使用 FBENCRYPT_* 定义而不是 Common Crypto 定义,这只会增加混乱和另一个可能出现错误的地方。

标签: ios security encryption ios7 aes


【解决方案1】:

快速猜测,因为信息不多:

数据使用与 PKCS#7(或 PKCS#5)不同的填充进行加密。 mcrypt(),虽然很流行,但由一些 bozos 编写并使用非标准的空填充,这既不安全,而且如果数据的最后一个字节是 0x00 将不起作用。

有关 PKCs#7 传递的更多信息,请参阅SO answer

如果填充明显不正确,CCCrypt 的早期版本会返回一个错误,这是一个后来被纠正的安全错误。 IIRC iOS7 是最后一个将错误填充报告为错误的版本。

【讨论】:

  • 我不知道 CCrypt 的变化。你对此有更多了解吗?如果 padding 不正确,它会返回什么?
  • 这在 Apple 论坛中被多次讨论,Quinn 参与了许多讨论。问题是一些开发人员使用错误返回来指示错误的密钥。基于 PKCS#7 填充,这工作得相当好,一个坏密钥有大约 255/256(左右)的机会产生一个填充错误。但这是一个安全漏洞,因此删除了奇偶校验,一些开发人员感到不安/充满敌意。现在,如果有奇偶校验错误,则不会报告错误。我看看能不能找到讨论。
  • @RobNapier 我找到了对填充错误处理的引用,这是gparker 来自 Apple 论坛的引用:出于安全原因,删除了 kCCDecodeError 的强制执行。 (查找“填充预言机攻击”。)另请参阅 Quinn 的以下回复。
  • 谢谢。 “或使用经过身份验证的加密算法。”呵呵……是的……openradar.me/11194903
  • 同样,错误报告 21468609 但 Apple 似乎对更新 iOS 加密不感兴趣。 EC 也不见了。
猜你喜欢
  • 1970-01-01
  • 2014-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
相关资源
最近更新 更多