0

I need to encrypt my data,so i encrypt them using AES. And I can encrypt short data.But I need to encrypt long data, it can't work.What can I do to fix this problem.This is my code.

#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;
}

When i encrypt data which has 96 byte, it will failed.I get this error "terminate called after throwing an instance of 'std::length_error' what(): basic_string::_S_create ".But I don't think this string is longer than max length.And I don't where is wrong.

Nicholas
  • 94
  • 2
  • 11
  • I encrypt 96 bytes data, and then I decrypt it , I get messy code,so I said it can't work. – Nicholas Aug 28 '15 at 03:11
  • Actually, I didn't splitting my bytes, I use this mode first time, so I don't know what should I do. – Nicholas Aug 28 '15 at 03:35
  • Is this any help to you? http://stackoverflow.com/questions/5132939/how-to-do-aes-decryption-using-openssl?rq=1 – Madness Aug 28 '15 at 03:36

2 Answers2

0

AES normally encrypts data by breaking it up into 16 byte blocks. If the last block is not 16 bytes long, it's padded to 16 bytes. Wiki articles:

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

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

rcgldr
  • 27,407
  • 3
  • 36
  • 61
0

You have nothing wrong in your encryption/decryption except for the padding issues and usage of strncpy and (char *) constructor when dealing with binary. You shouldn't encrypt last block of data if it doesn't fit all of the 16 bytes. So you should implement your own padding or don't encrypt last small block at all, your code will be simplified to this:

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());
 }

To summarize:

  • don't use strncpy() with binary
  • don't use string s = binary_char_massive; constructor
  • don't encrypt last portion of data if it doesn't fit to block size or pad it yourself
  • Use EVP_* openssl API if there is possibility of future algorithms change
Vladimir Kunschikov
  • 1,735
  • 1
  • 16
  • 16