【发布时间】:2015-03-09 21:54:23
【问题描述】:
我正在使用 VC++/OPENSSL 和 AES-256-CBC,我注意到由于 AES 是 OPENSSL 自动填充的,当我尝试解密时,我得到的数据是填充字节。不仅仅是原始数据。
是否有办法在解密时获取原始数据的长度,以便我可以削减填充字节?
这是我的代码
void Cryptology::OpenSSLAESDecodeByMapleArray(MapleByteArray& source, MapleByteArray& ba,MapleByteArray &res,bool nosalt)
{
EVP_CIPHER_CTX de;
unsigned int salt[] = { 56756, 352466 };
int i, nrounds = 7;
unsigned char key[32] = { 0 }, iv[32] = { 0 };
if (nosalt)
{
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), NULL, ba.data_ptr(), ba.GetLength(), nrounds, key, iv);
}
else
{
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), (unsigned char *)salt, ba.data_ptr(), ba.GetLength(), nrounds, key, iv);
}
if (i != 32) {
exit(0);
}
EVP_CIPHER_CTX_init(&de);
EVP_DecryptInit_ex(&de, EVP_aes_256_cbc(), NULL, key, iv);
int p_len = source.GetLength(), f_len = 0;
unsigned char *plaintext = (unsigned char *)malloc(p_len + AES_BLOCK_SIZE);
ZeroMemory(plaintext, p_len + AES_BLOCK_SIZE);
EVP_DecryptInit_ex(&de, NULL, NULL, NULL, NULL);
EVP_DecryptUpdate(&de, plaintext, &p_len, (unsigned char *)source.data_ptr(), source.GetLength());
EVP_DecryptFinal_ex(&de, plaintext + p_len, &f_len);
int len = p_len + f_len;
//qDebug() << QString::number(len);
EVP_CIPHER_CTX_cleanup(&de);
res.fromByte((BYTE*)plaintext, p_len + AES_BLOCK_SIZE);
ZeroMemory(plaintext, p_len + AES_BLOCK_SIZE);
free(plaintext);
ZeroMemory(key, 32);
ZeroMemory(iv, 32);
return;
}
【问题讨论】:
-
填充通常遵循一个约定(只是暂时不记得了),例如
ddddddppppb。其中d是数据字节,p是填充字节,b是填充字节数。 -
我看到了理查德。但是有没有让 OPENSSL 自动进行填充和取消填充?我懒得写代码了:P
-
最好用数据编码数据大小,不要依赖填充和一些自动数据大小扣除。如果编码数据被截断,您希望能够检测到这一点。这就是为什么您在数据前面编码数据大小并检查数据是否被截断的原因。然后,删除填充或可能在加密消息之后添加的任何垃圾都是微不足道的。您的代码将更加健壮。
-
快速阅读文档说 OpenSSL 使用 PKCS#7 填充,因此请在 OpenSSL 中找到 API 来添加/删除填充。
-
@chmike 如果您希望您的加密方案基于标准,则必须使用填充标准。例如,参见 PKCS#7 填充。
标签: c++ encryption aes