[英]OpenSSL AES_CBC-256 decrypting without original text length in C++
我有我在 SO 上找到的这段代码,它可以工作。 我的问题是加密和解密在同一个文件中。 自然,我想将它们分成两个功能。 问题是解码器需要原始输入长度。 这不是安全漏洞吗? 在不知道输入的原始长度的情况下如何解密?
/* computes the ciphertext from plaintext and key using AES256-CBC algorithm */
string cipher_AES(string key, string message)
{
size_t inputslength = message.length();
unsigned char aes_input[inputslength];
unsigned char aes_key[AES_KEYLENGTH];
memset(aes_input, 0, inputslength/8);
memset(aes_key, 0, AES_KEYLENGTH/8);
strcpy((char*) aes_input, message.c_str());
strcpy((char*) aes_key, key.c_str());
/* init vector */
unsigned char iv[AES_BLOCK_SIZE];
memset(iv, 0x00, AES_BLOCK_SIZE);
// buffers for encryption and decryption
const size_t encslength = ((inputslength + AES_BLOCK_SIZE) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE;
unsigned char enc_out[encslength];
unsigned char dec_out[inputslength];
memset(enc_out, 0, sizeof(enc_out));
memset(dec_out, 0, sizeof(dec_out));
AES_KEY enc_key, dec_key;
AES_set_encrypt_key(aes_key, AES_KEYLENGTH, &enc_key);
AES_cbc_encrypt(aes_input, enc_out, inputslength, &enc_key, iv, AES_ENCRYPT);
AES_set_decrypt_key(aes_key, AES_KEYLENGTH, &dec_key);
AES_cbc_encrypt(enc_out, dec_out, encslength, &dec_key, iv, AES_DECRYPT);
stringstream ss;
for(int i = 0; i < encslength; i++)
{
ss << enc_out[i];
}
return ss.str(););
}
首先,AES 加密在 128 位的块中以一对一的方式进行,因此您只需查看密文就已经知道了 16 字节精度的消息大小。
然后,对于最后一个块,您只需要确定消息在哪里结束。 对此的标准解决方案是使用填充(例如PKCS#7 )。 或者只是将消息长度存储在开头并将其与消息一起加密。
您当然可以继续使用 OpenSSL AES API,并自己实现填充或其他一些机制。 但是 OpenSSL 已经有更高级别的 API (EVP),它会自动进行 AES、CBC 和 PKCS 填充。
有关使用 EVP API 的示例,请参阅EVP 对称加密和解密官方 OpenSSL wiki 页面。
无关注释:
固定的 IV(尤其是零 IV)是不安全的。 考虑生成一个随机 IV 并将其与密文一起存储(例如使用RAND_bytes )。
还检查 AES GCM 模式以进行身份验证加密(加密 + 安全校验和),这样加密的消息也变得防篡改。 请参阅此示例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.