【问题标题】:How to encrypt data using AES(openssl)?如何使用 AES(openssl)加密数据?
【发布时间】:2015-08-28 02:34:45
【问题描述】:

我需要加密我的数据,所以我使用 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 “。但我不认为这个字符串比最大长度长。而且我不知道哪里错了。

【问题讨论】:

  • 我加密了96字节的数据,然后我解密了,我得到了乱码,所以我说它不能工作。
  • 其实我并没有拆分字节,我是第一次使用这种模式,所以不知道该怎么办。
  • 这对您有帮助吗? stackoverflow.com/questions/5132939/…

标签: c++ encryption openssl aes


【解决方案1】:

在处理二进制文件时,除了填充问题和 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());
 }

总结一下:

  • 不要将 strncpy() 与二进制文件一起使用
  • 不要使用string s = binary_char_massive;构造函数
  • 如果数据的最后一部分不适合块大小或自行填充,则不要加密它
  • 如果未来算法可能发生变化,请使用 EVP_* openssl API

【讨论】:

  • 谢谢,但我还有一个问题,纯文本的大小有限制吗?
  • 是的,string::max_size()
  • 我加密了一个字符串,所有的“a”都有 103 个字节,但我加密后只有 87 个字节,所以我想知道哪里出错了。
  • 显然你的长度计算有误
  • 长度计算?哪个?key?iv?or msg?
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 2013-01-07
    • 2012-04-10
    • 1970-01-01
    • 2013-08-12
    相关资源
    最近更新 更多