Does AES_cbc_encrypt add padding?(AES_cbc_encrypt 是否添加填充?)
问题描述
考虑以下 C++ 代码片段:
Consider the following snippet of C++ code:
#include <iostream>
#include <openssl/aes.h>
#define AES_KEY_LENGTH 32
using namespace std;
int main()
{
AES_KEY encryption_key;
AES_KEY decryption_key;
unsigned char key[AES_KEY_LENGTH] = {'t', 'e', 's', 't', 't', 'e', 's', 't', 't', 'e', 's', 't', 't', 'e', 's', 't', 't', 'e', 's', 't', 't', 'e', 's', 't', 't', 'e', 's', 't', 't', 'e', 's', 't'};
unsigned char iv[AES_BLOCK_SIZE] = {'t', 'e', 's', 't', 't', 'e', 's', 't', 't', 'e', 's', 't', 't', 'e', 's', 't'};
unsigned char iv_enc[AES_BLOCK_SIZE];
unsigned char iv_dec[AES_BLOCK_SIZE];
memcpy(iv_enc, iv, AES_BLOCK_SIZE);
memcpy(iv_dec, iv, AES_BLOCK_SIZE);
AES_set_encrypt_key(key, AES_KEY_LENGTH * 8, &(encryption_key));
AES_set_decrypt_key(key, AES_KEY_LENGTH * 8, &(decryption_key));
char message[] = "Attack at dawn! Attack.";
unsigned char * encryption_output = new unsigned char[32];
encryption_output[31] = 3;
AES_cbc_encrypt((unsigned char *) message, encryption_output, sizeof(message), &encryption_key, iv_enc, AES_ENCRYPT);
unsigned char * decryption_output = new unsigned char[32];
AES_cbc_encrypt(encryption_output, decryption_output, 32, &decryption_key, iv_dec, AES_DECRYPT);
}
我在这里做的是使用 openssl aes 库加密然后解密消息.我关心的是长度encryption_output.就我的理解而言,由于 AES 以大小为 AES_BLOCK_SIZE(又名 16 字节)的块进行加密,因此输出字节数应等于消息的大小,四舍五入到最接近的 AES_BLOCK_SIZE 倍数.这个对吗?特别是,如果我将消息扩展为恰好 32 个字节长,会发生什么情况?这仍然有效,还是会添加 16 个空填充字节,从而在尝试在加密输出中写入字节 32 到 47 时导致分段错误?
What I do here is encrypt and then decrypt a message using openssl aes library. What I am concerned about is the length encryption_output. As far as my understanding goes, since AES encrypts in blocks of size AES_BLOCK_SIZE (aka 16 bytes) the number of output bytes should be equal to the size of the message, rounded up to the closest multiple of AES_BLOCK_SIZE. Is this correct? In particular, what happens if I extend the message to be exactly 32 bytes long? Will this still work, or will 16 empty padding bytes be added thus causing a segmentation fault when trying to write bytes 32 to 47 in encryption_output?
推荐答案
正确的 PKCS#7 填充:
Proper PKCS#7 padding:
- 将长度四舍五入为块大小的倍数 如果它不是之前的倍数
- 它添加一个完整的块否则
- rounds the length up to a multiple of the blocksize if it wasn´t a multiple before
- and it adds a whole block otherwise
否则,在解密时,您不可能知道最后一个密文块是真实的"还是仅填充.(也指定了要填充的实际字节值,但是您真正的最后一个块可能包含这些 => 再次无法识别它).
Else, when decrypting, you couldn´t possibly know if the last ciperhtext block is "real" or only padding. (The actual byte values to pad with are specified too, but your real last block could contain these => again not possible to recognize it).
除了 PKCS#7 之外还有其他方案,但这与此处无关.
There are other schemes than PKCS#7, but this is not relevant here.
但是,使用 AES_cbc_encrypt
,您必须自己实现,即.加密前填充,解密后去除填充.加密本身适用于非多个长度,但使用的填充"存在上述问题.要回答您的原始问题,AES_cbc_encrypt
不会添加块,它唯一能做的就是将长度四舍五入.
However, with AES_cbc_encrypt
, you´ll have to implement this yourself, ie. pad before encrypting and remove the padding after decrypting. The encrypting itself will work with non-multiple lengths, but the used "padding" has the problem mentioned above. To answer your original question, AES_cbc_encrypt
won´t add blocks, rounding up the length is the only thing it does.
对于具有适当填充的函数(并且没有 AES_cbc_encrypt
的其他几个缺点,例如缺少 AESNI 支持等),请查看 OpenSSL 的 EVP 部分.AES_cbc_encrypt
是一个更底层的部分,这取决于它也被高级函数使用的情况.
For functions with proper padding (and without several other disadvantages of AES_cbc_encrypt
, like missing AESNI support etc.etc.), look into the EVP part of OpenSSL. AES_cbc_encrypt
is a more lowlevel part, depending on the situation it´s used by the highlevel function too.
顺便说一句,关于 C++:如果你没有遇到分段错误,
这并不意味着代码是正确的.
Btw., something about C++: If you don´t get a segmentation fault,
it doesn´t mean that the code is correct.
这篇关于AES_cbc_encrypt 是否添加填充?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:AES_cbc_encrypt 是否添加填充?
基础教程推荐
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 从 std::cin 读取密码 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07