パディングなしで CFB モードで SecTransformExecute を使用しようとしています。入力と同じデータサイズで暗号化された結果を取得しようとしています (暗号文を作成するために、ブロックで生成されたキーストリームに対してプレーンテキストを XOR するだけなので、CFB はこれを行う必要があると思います。ただし、私のテストコードは以下のとおりです。パディング オプションを使用しても使用しなくても、20 バイトの文字列では同じ結果になるようです. 不思議なことに、32 バイトの文字列には、変換によって 16 バイトのパディングが追加されているようです. たぶん、このレベルのコントロール?ここで何が欠けていますか?次のピースの 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>