我正在尝试在没有填充的 CFB 模式下使用 SecTransformExecute。我正在尝试获得与输入数据大小相同的加密结果(我相信 CFB 应该这样做,因为它只是将明文与块生成的密钥流进行异或以创建密文。但是,我的测试代码如下,它似乎是否使用填充选项会导致 20 字节字符串的结果相同。奇怪的是,一个 32 字节的字符串似乎通过转换添加了 16 个字节的填充。也许我需要下拉到 CommonCrypto 这个级别控制?我在这里错过了什么?我想创建一些东西,我可以通过将最后一个块作为下一块的 iv 传递,将新的加密数据链接到末尾。安全转换似乎没有可用的 CTR 模式.
CFErrorRef error = NULL;
// 16 byte buffer with random data for iv
NSData *iv = [NSMutableData dataWithLength:16];
arc4random_buf((void *)[iv bytes], 16);
DDLogVerbose(@"iv: %@, length: %lu", iv, [iv length]);
// something to encrypt
NSString *plainText = @"I'm a secret string."; // 20 bytes
NSData *plainData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
DDLogVerbose(@"plainText : %lu : %@", [plainText length], plainText);
DDLogVerbose(@"plainData : %lu : %@", [plainData length], plainData);
// setup padding encryptor
SecTransformRef encryptPadded = SecEncryptTransformCreate(key, &error);
SecTransformSetAttribute(encryptPadded, kSecModeCFBKey, NULL, &error);
SecTransformSetAttribute(encryptPadded, kSecPaddingKey, kSecPaddingPKCS7Key, &error);
SecTransformSetAttribute(encryptPadded, kSecIVKey, (__bridge CFTypeRef)(iv), &error);
SecTransformSetAttribute(encryptPadded, kSecTransformInputAttributeName, (__bridge CFTypeRef)(plainData), &error);
// encrypt with it
NSData *cipherDataPadded = (__bridge NSData *) SecTransformExecute(encryptPadded, &error);
DDLogVerbose(@"cipherDataPadded : %lu : %@", [cipherDataPadded length], cipherDataPadded);
// setup unpadded encryptor
SecTransformRef encryptUnpadded = SecEncryptTransformCreate(key, &error);
SecTransformSetAttribute(encryptUnpadded, kSecModeCFBKey, NULL, &error);
SecTransformSetAttribute(encryptUnpadded, kSecPaddingKey, kSecPaddingNoneKey, &error);
SecTransformSetAttribute(encryptUnpadded, kSecIVKey, (__bridge CFTypeRef)(iv), &error);
SecTransformSetAttribute(encryptUnpadded, kSecTransformInputAttributeName, (__bridge CFTypeRef)(plainData), &error);
// encrypt with it
NSData *cipherDataUnpadded = (__bridge NSData *) SecTransformExecute(encryptUnpadded, &error);
DDLogVerbose(@"cipherDataUnpadded : %lu : %@", [cipherDataUnpadded length], cipherDataUnpadded);
// something to encrypt
NSString *plainText32 = @"I'm a secret string of 32 bytes."; // 20 bytes
NSData *plainData32 = [plainText32 dataUsingEncoding:NSUTF8StringEncoding];
DDLogVerbose(@"plainText32 : %lu : %@", [plainText32 length], plainText32);
DDLogVerbose(@"plainData32 : %lu : %@", [plainData32 length], plainData32);
// setup padded encryptor for 32 bytes
SecTransformRef encryptPadded32 = SecEncryptTransformCreate(key, &error);
SecTransformSetAttribute(encryptPadded32, kSecModeCFBKey, NULL, &error);
SecTransformSetAttribute(encryptPadded32, kSecPaddingKey, kSecPaddingPKCS7Key, &error);
SecTransformSetAttribute(encryptPadded32, kSecIVKey, (__bridge CFTypeRef)(iv), &error);
SecTransformSetAttribute(encryptPadded32, kSecTransformInputAttributeName, (__bridge CFTypeRef)(plainData32), &error);
// encrypt with it
NSData *cipherDataPadded32 = (__bridge NSData *) SecTransformExecute(encryptPadded32, &error);
DDLogVerbose(@"cipherDataPadded32 : %lu : %@", [cipherDataPadded32 length], cipherDataPadded32);
// setup unpadded encryptor for 32 bytes
SecTransformRef encryptUnpadded32 = SecEncryptTransformCreate(key, &error);
SecTransformSetAttribute(encryptUnpadded32, kSecModeCFBKey, NULL, &error);
SecTransformSetAttribute(encryptUnpadded32, kSecPaddingKey, kSecPaddingNoneKey, &error);
SecTransformSetAttribute(encryptUnpadded32, kSecIVKey, (__bridge CFTypeRef)(iv), &error);
SecTransformSetAttribute(encryptUnpadded32, kSecTransformInputAttributeName, (__bridge CFTypeRef)(plainData32), &error);
// encrypt with it
NSData *cipherDataUnpadded32 = (__bridge NSData *) SecTransformExecute(encryptUnpadded32, &error);
DDLogVerbose(@"cipherDataUnpadded32: %lu : %@", [cipherDataUnpadded32 length], cipherDataUnpadded32);
产生以下输出:
>>> plainText : 20 : I'm a secret string.
>>> plainData : 20 : <49276d20 61207365 63726574 20737472 696e672e>
>>> cipherDataPadded : 32 : <54e26843 a6e96b71 6ebe4605 5c10ec1e 28b9c87a a2574f21 66e788c4 dfca3f32>
>>> cipherDataUnpadded : 32 : <54e26843 a6e96b71 6ebe4605 5c10ec1e 28b9c87a a2574f21 66e788c4 dfca3f32>
>>> plainText32 : 32 : I'm a secret string of 32 bytes.
>>> plainData32 : 32 : <49276d20 61207365 63726574 20737472 696e6720 6f662033 32206279 7465732e>
>>> cipherDataPadded32 : 48 : <54e26843 a6e96b71 6ebe4605 5c10ec1e 63cd5eaf 5e86fb77 d672cd15 528f19b5 2b0bcff4 c5cb2ca6 bc195f9d bba54baf>
>>> cipherDataUnpadded32: 48 : <54e26843 a6e96b71 6ebe4605 5c10ec1e 63cd5eaf 5e86fb77 d672cd15 528f19b5 2b0bcff4 c5cb2ca6 bc195f9d bba54baf>