对于 CTR 模式,我是否需要输出缓冲区是 AES 块大小的倍数?
Do I need output buffer to be multiple of AES block size for CTR mode?
在我的C代码中,我在CTR模式下使用OpenSSL的AES通过EVP接口进行加密,也就是说我有这样的东西:
ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, iv))
...
ret = EVP_EncryptUpdate(ctx, out, &outlen, in, inlen);
输入数据的长度不是 AES 块大小的倍数,因此如果使用 CBC 模式,我将不得不为输出缓冲区中的填充分配额外的字节。
我需要在 CTR 模式下做同样的事情吗? 另外我对 CFB 和 OFB 模式很好奇。
EVP_EncryptUpdate 上的 OpenSSL man 没有说任何关于 "stream-like" 模式的具体信息,他们只是警告需要额外的字节来填充。
Do I need output buffer to be multiple of AES block size for CTR mode?
不,点击率模式没有这个要求。在这方面,CTR 模式类似于 OFB 和 CFB 模式。相比之下,ECB 和 CBC 模式需要块大小的倍数。
OpenSSL 使用 Init/Update/Final 模式,输入和输出字节都被缓冲直到需要。如果愿意,您可以一次插入一个字节。
在内部,EVP 对象将缓冲输入,直到有足够的输入来执行加密。由于 CTR 模式可以流式传输,因此在处理一个输入字节后将有一个输出字节可用(它是加密计数器与纯文本的简单异或)。 EVP 对象还将缓冲输出字节,直到您调用 Final。
TLDR:EVP 不填充 CTR(和其他流 modes/ciphers)
实际上 EVP_EncryptUpdate
本身从不填充,尽管它可以 'carry' 从一个调用到下一个调用的部分块;因此,如果您代码中的 ...
不包含任何先前的 EncryptUpdate
,那么这个(第一个)EncryptUpdate
将始终是块对齐的,并且其输出永远不会更长:
EVP_EncryptUpdate() encrypts inl bytes from the buffer in and writes the encrypted version to out. This function can be called multiple times to encrypt successive blocks of data. The amount of data written depends on the block alignment of the encrypted data: as a result the amount of data written may be anything from zero bytes to (inl + cipher_block_size - 1) so out should contain sufficient room. The actual number of bytes written is placed in outl. It also checks if in and out are partially overlapping, and if they are 0 is returned to indicate failure.
EVP_EncryptFinal[_ex]
添加填充,因此在需要时 'extra' 输出,如手册页下一段所述:
If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts the "final" data, that is any data that remains in a partial block. It uses standard block padding (aka PKCS padding) as described in the NOTES section, below. The encrypted final data is written to out which should have sufficient space for one cipher block. The number of bytes written is placed in outl. After this function is called the encryption operation is finished and no further calls to EVP_EncryptUpdate() should be made.
If padding is disabled then EVP_EncryptFinal_ex() will not encrypt any more data and it will return an error if any data remains in a partial block: that is if the total data length is not a multiple of the block size.
但是,由于密文实际上包含所有 Update
调用的输出(或者如果只有一个调用)加上 [=16] 的输出=]调用,总缓冲区确实需要(最多)比输入大一个块在填充应用的情况下。
手册页没有说(也应该说)的是填充根本不适用于流密码(如 RC4)或流模式(包括 CTR OFB* CFB*)。每个 cipher/mode 组合都由一个 EVP_CIPHER
类型的对象描述,它是 struct evp_cipher_st
的类型定义;这是 EVP_aes_256_ctr()
和类似例程 return 的指针。此结构包含一个字段 block_size
,您猜对了,其中包含块大小(以字节为单位)。对于流模式和密码,它包含一个经过特殊处理的虚拟值 1:EncryptFinal_ex
即使启用也不添加填充,并且 DecryptFinal_ex
即使启用也不删除和检查填充。
在我的C代码中,我在CTR模式下使用OpenSSL的AES通过EVP接口进行加密,也就是说我有这样的东西:
ret = EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, key, iv))
...
ret = EVP_EncryptUpdate(ctx, out, &outlen, in, inlen);
输入数据的长度不是 AES 块大小的倍数,因此如果使用 CBC 模式,我将不得不为输出缓冲区中的填充分配额外的字节。
我需要在 CTR 模式下做同样的事情吗? 另外我对 CFB 和 OFB 模式很好奇。
EVP_EncryptUpdate 上的 OpenSSL man 没有说任何关于 "stream-like" 模式的具体信息,他们只是警告需要额外的字节来填充。
Do I need output buffer to be multiple of AES block size for CTR mode?
不,点击率模式没有这个要求。在这方面,CTR 模式类似于 OFB 和 CFB 模式。相比之下,ECB 和 CBC 模式需要块大小的倍数。
OpenSSL 使用 Init/Update/Final 模式,输入和输出字节都被缓冲直到需要。如果愿意,您可以一次插入一个字节。
在内部,EVP 对象将缓冲输入,直到有足够的输入来执行加密。由于 CTR 模式可以流式传输,因此在处理一个输入字节后将有一个输出字节可用(它是加密计数器与纯文本的简单异或)。 EVP 对象还将缓冲输出字节,直到您调用 Final。
TLDR:EVP 不填充 CTR(和其他流 modes/ciphers)
实际上 EVP_EncryptUpdate
本身从不填充,尽管它可以 'carry' 从一个调用到下一个调用的部分块;因此,如果您代码中的 ...
不包含任何先前的 EncryptUpdate
,那么这个(第一个)EncryptUpdate
将始终是块对齐的,并且其输出永远不会更长:
EVP_EncryptUpdate() encrypts inl bytes from the buffer in and writes the encrypted version to out. This function can be called multiple times to encrypt successive blocks of data. The amount of data written depends on the block alignment of the encrypted data: as a result the amount of data written may be anything from zero bytes to (inl + cipher_block_size - 1) so out should contain sufficient room. The actual number of bytes written is placed in outl. It also checks if in and out are partially overlapping, and if they are 0 is returned to indicate failure.
EVP_EncryptFinal[_ex]
添加填充,因此在需要时 'extra' 输出,如手册页下一段所述:
If padding is enabled (the default) then EVP_EncryptFinal_ex() encrypts the "final" data, that is any data that remains in a partial block. It uses standard block padding (aka PKCS padding) as described in the NOTES section, below. The encrypted final data is written to out which should have sufficient space for one cipher block. The number of bytes written is placed in outl. After this function is called the encryption operation is finished and no further calls to EVP_EncryptUpdate() should be made.
If padding is disabled then EVP_EncryptFinal_ex() will not encrypt any more data and it will return an error if any data remains in a partial block: that is if the total data length is not a multiple of the block size.
但是,由于密文实际上包含所有 Update
调用的输出(或者如果只有一个调用)加上 [=16] 的输出=]调用,总缓冲区确实需要(最多)比输入大一个块在填充应用的情况下。
手册页没有说(也应该说)的是填充根本不适用于流密码(如 RC4)或流模式(包括 CTR OFB* CFB*)。每个 cipher/mode 组合都由一个 EVP_CIPHER
类型的对象描述,它是 struct evp_cipher_st
的类型定义;这是 EVP_aes_256_ctr()
和类似例程 return 的指针。此结构包含一个字段 block_size
,您猜对了,其中包含块大小(以字节为单位)。对于流模式和密码,它包含一个经过特殊处理的虚拟值 1:EncryptFinal_ex
即使启用也不添加填充,并且 DecryptFinal_ex
即使启用也不删除和检查填充。