1

パディングなしで 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>
4

1 に答える 1

0

どんなものSecKeyを使っていますか?たとえば、AES128-CFB は 16 バイト境界までパディングする必要があります (cipherDataUnpadded は を与えますnull)。

CFB には、使用される暗号化アルゴリズムに応じた「ブロック」の概念しかありません (AES128 と AES256 は 2 つの異なるアルゴリズムです)。

また、PKCS#7 パディングは、そうでなければブロック サイズを満たす長さであっても、メッセージの長さに少なくとも 1 オクテットを追加することに注意してください。 RFC5652を参照してください。

于 2013-09-01T21:04:50.950 に答える