如何使用AES(openssl)加密数据

How to encrypt data using AES(openssl)?

本文关键字:加密 数据 openssl 何使用 AES      更新时间:2023-10-16

我需要加密我的数据,所以我使用AES加密它们。我可以加密短数据。但我需要加密长数据,这行不通。我能做些什么来解决这个问题?这是我的代码。

#include "cooloi_aes.h"
CooloiAES::CooloiAES()
  : MSG_LEN(0)
{
  for(int i = 0; i < AES_BLOCK_SIZE; i++)
  {
     key[i] = 32 + i;
  }
}
CooloiAES::~CooloiAES()
{
}
std::string CooloiAES::aes_encrypt(std::string msg)
{
     int i = msg.size() / 1024;
     MSG_LEN = ( i + 1 ) * 1024;
char in[MSG_LEN];
char out[MSG_LEN];
memset((char*)in,0,MSG_LEN);
memset((char*)out,0,MSG_LEN);
strncpy((char*)in,msg.c_str(),msg.size());
unsigned char iv[AES_BLOCK_SIZE];
for(int j = 0; j < AES_BLOCK_SIZE; ++j)
{
    iv[j] = 0;
}
AES_KEY aes;
if(AES_set_encrypt_key((unsigned char*)key, 128, &aes) < 0)
{
    return NULL;
}
int len = msg.size();
AES_cbc_encrypt((unsigned char*)in,(unsigned char*)out,len,&aes,iv,AES_ENCRYPT);
std::string encrypt_msg(&out[0],&out[MSG_LEN+16]);
std::cout << std::endl;
return encrypt_msg;
}
std::string CooloiAES::aes_decrypt(std::string msg)
{
   MSG_LEN = msg.size();
   char in[MSG_LEN];
char out[MSG_LEN+16];
memset((char*)in,0,MSG_LEN);
memset((char*)out,0,MSG_LEN+16);
strncpy((char*)in,msg.c_str(),msg.size());
std::cout << std::endl;
unsigned char iv[AES_BLOCK_SIZE];
for(int j = 0; j < AES_BLOCK_SIZE; ++j)
{
    iv[j] = 0;
}
AES_KEY aes;
if(AES_set_decrypt_key((unsigned char*)key, 128, &aes) < 0)
{
    return NULL;
}
int len = msg.size();
AES_cbc_encrypt((unsigned char*)in,(unsigned char*)out,len,&aes,iv,AES_DECRYPT);
std::string decrypt_msg = out;
return decrypt_msg;
}

当我加密96字节的数据时,它将失败。我得到这个错误"在抛出'std::length_error'实例后调用终止"(): basic_string: _S_create".但我不认为这个字符串超过最大长度。我不知道哪里错了

除了填充问题和处理二进制时strncpy和(char *)构造函数的使用之外,您的加密/解密没有任何错误。如果最后一个数据块不适合所有16字节,则不应该加密。因此,您应该实现自己的填充或不加密最后一小块,您的代码将简化为:

string aes_encrypt/decrypt(string msg)
 {
       unsigned char out[msg.size()];
       memcpy((char*)out,msg.data(),msg.size());
       AES_cbc_encrypt((unsigned char *)msg.data(),out,msg.size()/16*16,&aes,iv,AES_ENCRYPT **or** AES_DECRYPT);
       return string((char *)out, msg.size());
 }

总结:

  • 不要在binary
  • 中使用strncpy()
  • 不要使用string s = binary_char_massive;构造器
  • 不加密数据的最后一部分,如果它不适合块大小或自己填充它
  • 使用EVP_* openssl API,如果有可能在未来的算法改变

AES通常通过将数据分解为16字节块来加密数据。如果最后一个块不是16字节长,则填充为16字节。Wiki文章:

http://en.wikipedia.org/wiki/Advanced_Encryption_Standard

http://en.wikipedia.org/wiki/AES_implementations