c++ - C++ AES 加密被截断为 16 个字符
问题描述
我有一个不久前在 C++ 中工作过的函数,它使用 CBC 进行 AES 256 加密。
我前段时间写了这个方法,所以不幸的是我不记得我从哪里得到代码,但我发现我有一个问题,如果被加密的字符串超过 16 个字符,它只有前 16 个字符被加密的字符串。
代码如下:
string Encryption::encryptOrDecrypt(string stringToEncrypt, Mode mode)
{
HelperMethods helperMethods;
try
{
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_CIPHER_CTX_init(ctx);
unsigned char key[33] = "my_key";
unsigned char iv[17] = "my_iv";
if (mode == Decrypt)
{
stringToEncrypt = helperMethods.base64Decode(stringToEncrypt);
}
vector<unsigned char> encrypted;
size_t max_output_len = stringToEncrypt.length() + 16 - (stringToEncrypt.length() % 16);
//size_t max_output_len = 16 - (stringToEncrypt.length() % 16);
encrypted.resize(max_output_len);
EVP_CipherInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv, mode);
// EVP_CipherUpdate can encrypt all your data at once, or you can do
// small chunks at a time.
int actual_size = 0;
EVP_CipherUpdate(ctx,
&encrypted[0], &actual_size,
reinterpret_cast<unsigned char *>(&stringToEncrypt[0]), stringToEncrypt.size());
// EVP_CipherFinal_ex is what applies the padding. If your data is
// a multiple of the block size, you'll get an extra AES block filled
// with nothing but padding.
int final_size = 0;
EVP_CipherFinal_ex(ctx, &encrypted[actual_size], &final_size);
actual_size += final_size;
encrypted.resize(actual_size);
char * buff_str = (char*)malloc(encrypted.size() * 2 + 1);
memset(buff_str, 0, (encrypted.size() * 2 + 1));
char * buff_ptr = buff_str;
size_t index = 0;
for (index = 0; index < encrypted.size(); ++index)
{
buff_ptr += sprintf(buff_ptr, "%c", encrypted[index]);
}
EVP_CIPHER_CTX_cleanup(ctx);
EVP_CIPHER_CTX_free(ctx);
if (mode == Encrypt)
{
string encryptedString = buff_str;
free(buff_str);
return helperMethods.base64Encode(encryptedString.c_str(), encryptedString.length());
}
else
{
string decryptedString = buff_str;
free(buff_str);
return decryptedString;
}
}
catch (exception ex)
{
return stringToEncrypt;
}
}
我已经通过代码查看问题可能出在哪里,但我看不出任何原因,这可能是愚蠢的简单。
是size_t max_output_len
768(实际字符串是 752),所以我相信这是 +16 的填充,但我不确定这是否也应该是 768,但由于方法本身不确定。
int final_size
当该方法完成时,传入的指针EVP_CipherFinal_ex
变为 16,并且actual_size
也是 768,因此不确定问题出在哪里。
解决方案
我想我已经找到了问题所在,尽管不是 100% 确定为什么会这样,而原来的方式却没有。
在调试时查看缓冲区的内容,我不相信它是一个空字节,但我已将其更改为以下似乎可以解决它的内容。
代替
string encryptedString = buff_str;
我已将其更改为以下
int i = 0;
stringstream encryptedStringStream;
for (i = 0; i < index; i++)
{
encryptedStringStream << buff_str[i];
}
string encryptedString = encryptedStringStream.str();