AES 解密在 iOS 7 中的行为与 iOS 8/9 中的行为不同
AES Decryption has different behavior in iOS 7 than iOS 8/9
以下方法 returns 运行 在 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。但是在iOS7.
上解密结果为nil
decryptedSize
执行后为0。 buffer
个元素保持为 0。
一些定义是
#define FBENCRYPT_ALGORITHM kCCAlgorithmAES128
#define FBENCRYPT_BLOCK_SIZE kCCBlockSizeAES128
#define FBENCRYPT_KEY_SIZE kCCKeySizeAES256
我在 SO 上阅读了类似 CCCrypt()
问题的答案。尝试了以下方法:
- 将
cKey
长度增加 1
- 将
cKey
长度增加到 FBENCRYPT_KEY_SIZE * 2 + 1
- 将
cKey
的第一个字节设置为 0(有人说 iOS 6 在从 NSString 获取关键字节时这样做)
None以上作品
调用该方法时,我返回了一些示例数据。
传给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
。
快速猜测,因为可以继续的信息很少:
数据使用与 PKCS#7(或 PKCS#5)不同的填充加密。 mcrypt()
,虽然 popular 是由一些 bozos 编写的,并使用非标准的空填充,这既不安全,也不会在数据的最后一个字节为 0x00 时起作用。
有关 PKC#7 通过的更多信息,请参阅此 。
如果填充明显不正确,CCCrypt
的早期版本会 return 出错,这是一个安全错误,后来得到纠正。 IIRC iOS7 是最后一个报告错误填充的版本。
以下方法 returns 运行 在 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。但是在iOS7.
上解密结果为nildecryptedSize
执行后为0。 buffer
个元素保持为 0。
一些定义是
#define FBENCRYPT_ALGORITHM kCCAlgorithmAES128
#define FBENCRYPT_BLOCK_SIZE kCCBlockSizeAES128
#define FBENCRYPT_KEY_SIZE kCCKeySizeAES256
我在 SO 上阅读了类似 CCCrypt()
问题的答案。尝试了以下方法:
- 将
cKey
长度增加 1 - 将
cKey
长度增加到FBENCRYPT_KEY_SIZE * 2 + 1
- 将
cKey
的第一个字节设置为 0(有人说 iOS 6 在从 NSString 获取关键字节时这样做)
None以上作品
调用该方法时,我返回了一些示例数据。
传给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
。
快速猜测,因为可以继续的信息很少:
数据使用与 PKCS#7(或 PKCS#5)不同的填充加密。 mcrypt()
,虽然 popular 是由一些 bozos 编写的,并使用非标准的空填充,这既不安全,也不会在数据的最后一个字节为 0x00 时起作用。
有关 PKC#7 通过的更多信息,请参阅此
如果填充明显不正确,CCCrypt
的早期版本会 return 出错,这是一个安全错误,后来得到纠正。 IIRC iOS7 是最后一个报告错误填充的版本。