AES Decryption has different behavior in iOS 7 tha

2019-03-31 18:39发布

问题:

The following method returns different results when run on iOS 7 than it does on 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;
}

Encryption works on iOS 7/8/9. But the decryption result is nil on iOS 7.

decryptedSize is 0 after execution. buffer elements remains 0.

Some definitions are

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

I have read answers to similar CCCrypt() questions on SO. Tried the following:

  1. Increase cKey length by 1
  2. Increase cKey length to FBENCRYPT_KEY_SIZE * 2 + 1
  3. Set the first byte of cKey to 0 (Some say iOS 6 does this when getting the key bytes from a NSString)

None of the above works.


I'm back with some sample data when the method is called.

The three parameters passed to decryptData is:

  • data: ea1e6896 b5731f40 1d560a18 f0729fa6,
  • key: 17c76e90 9a6fef8d b1fd45fa 2de18db0 d2236264 db6c8a60 125599ec 2dfb5614, 256 bits for AES256
  • iv: 41463531 38453234 44333835 42463636, 16-byte which is the same as block size

Expected result (and the actual result on iOS8/9) is 248e51af 66bf85d3 00003ab6 fe3c0000.

回答1:

Quick guess since there is little information to go on:

The data was encrypted with a different padding that PKCS#7 (or PKCS#5). mcrypt(), while popular was written by some bozos and uses non-standard null padding which is both insecure and will not work if the last byte of the data is 0x00.

For more information on PKCs#7 passing see this SO answer.

Early versions of CCCrypt would return an error if the padding was obviously incorrect, that was a security error which was later corrected. IIRC iOS7 was the last version that reported bad padding as an error.