CCCryptorCreateWithMode 忽略填充参数

CCCryptorCreateWithMode ignores padding parameter

我正在尝试使用 CommonCrypto 通过 AES-CTR 和 PKCS7 填充进行加密。

我知道 CTR 不需要 填充才能正常工作,除此之外还有其他用途。引用 RFC 3686:

For this reason, AES-CTR does not require the plaintext to be padded to a multiple of the block size. However, to provide limited traffic flow confidentiality, padding MAY be included, as specified in ESP.

参考文档的

Section 2.4 是相关的,并列出了填充的几种用法。

因此,我认为 CommonCrypto 应该能够将填充应用于 any 密码(模式)。代码看起来很简单,分解成这样:

CCCryptorRef cryptor = nil;
NSData* input = [NSMutableData dataWithLength:3];
NSData* key = [NSMutableData dataWithLength:32];
NSMutableData* output = [NSMutableData dataWithLength:32];

CCCryptorCreateWithMode(
        kCCEncrypt, kCCModeCTR, kCCAlgorithmAES, ccPKCS7Padding,
        nil,
        key.bytes, key.length,
        nil, 0, 0,
        kCCModeOptionCTR_BE,
        &cryptor
);

size_t written = 0;
CCCryptorUpdate(
        cryptor,
        input.bytes, input.length,
        output.mutableBytes, output.length,
        &written
);

size_t writtenF = 0;
CCCryptorFinal(
    cryptor, 
    output.mutableBytes + written, output.length - written, 
    &writtenF);

CCCryptorRelease(cryptor);

output.length = written + writtenF;

NSLog(@"Expected: 16 bytes");
NSLog(@"Actual: %i bytes", output.length);

输出为:

Expected: 16 bytes
Actual: 3 bytes

如果您检查状态代码,您会发现没有任何错误。

我可以很好地解密输出,所以加密本身似乎工作得很好。但显然没有填充发生。

我无法调试实现,所以我不知道出了什么问题。我是不是用错了选项?


注意:我可以 CCCrypt 使用 kCCOptionPKCS7Padding 应用填充,但我看不到 select CTR 模式的方法。

这是对答案的尝试,最终没有成功,希望其他人可以使用指针并更了解情况。


ccSetupCryptorimplementation 中(由 CCCryptorCreateWithMode 调用)我们发现:

case ccPKCS7Padding:
        if(mode == kCCModeCBC)
            ref->padptr = &ccpkcs7_pad;
        else
            ref->padptr = &ccpkcs7_ecb_pad;
        break;

这似乎表明 PKCS7 仅适用于 CBC 和 ECB。

但是填充应该做一些事情。深入挖掘,ccpkcs7_ecb_pad 定义在 corecryptoSymmetricBridge:

const cc2CCPaddingDescriptor ccpkcs7_ecb_pad = {
    .encrypt_pad = ccpkcs7_encrypt_ecb_pad,
    .decrypt_pad = ccpkcs7_decrypt_ecb_pad,
    .padlen = ccpkcs7_padlen,
    .padreserve = ccpkcs7_reserve,
};

ccpkcs7_encrypt_ecb_pad 导致 an actual encryption routine,我确定它不会在 CTR 模式下执行。

跟踪 ccpkcs7_padlen 将我引向此:

static size_t ccctr_mode_get_block_size(const corecryptoMode modeObject) { 
    return modeObject.ctr->block_size; 
}

现在,这个 corecryptoMode 是在 corecryptoSymmetricBridge 中定义的,但我无法在那里或其他任何地方找到 block_size 的定义。

对于所有 AES 模式,应该 为 128 位,但由于 CTR 可以处理任意长度的输入,因此可能设置为零或一? 解释为什么添加零填充字节,但我无法确认会发生什么。

Quoting RFC 3686:

For this reason, AES-CTR does not require the plaintext to be padded to a multiple of the block size. However, to provide limited traffic flow confidentiality, padding MAY be included, as specified in ESP.

这是填充的不同用法。它是 not PKCS#7 块密码中使用的填充。它是 RFC 2406 padding 放在有效载荷数据后面的 ESP 数据包中(见下文)。


Therefore, I figure CommonCrypto should be able to apply padding to any cipher (mode)...

混乱使您陷入了困境。它不像你想的那样与 CommonCrypto 相交。现在停止:)


来自 RFC 2406 的第 2 页:

2.  Encapsulating Security Payload Packet Format

   The protocol header (IPv4, IPv6, or Extension) immediately preceding
   the ESP header will contain the value 50 in its Protocol (IPv4) or
   Next Header (IPv6, Extension) field [STD-2].

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ----
|               Security Parameters Index (SPI)                 | ^Auth.
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Cov-
|                      Sequence Number                          | |erage
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ----
|                    Payload Data* (variable)                   | |   ^
~                                                               ~ |   |
|                                                               | |Conf.
+               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Cov-
|               |     Padding (0-255 bytes)                     | |erage*
+-+-+-+-+-+-+-+-+               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |   |
|                               |  Pad Length   | Next Header   | v   v
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ------
|                 Authentication Data (variable)                |
~                                                               ~
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+