Roman
Roman

Reputation: 559

OpenSSL AES wrong encryption

I have a some code below. My problem that i have a strange ending of encrypted and decrypted char array.

#include <iostream>
#include <openssl\evp.h>

#define AES_BLOCK_SIZE 16

static EVP_CIPHER_CTX Encrypt_Context, Decrypt_Context;

int aes_init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx, 
             EVP_CIPHER_CTX *d_ctx)
{
  int i, nrounds = 1;
  unsigned char key[16], iv[16];

  i = EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv);
  if (i != 16) {
    printf("Key size is %d bits - should be 128 bits\n", i);
    return -1;
  }

  EVP_CIPHER_CTX_init(e_ctx);
  EVP_EncryptInit_ex(e_ctx, EVP_aes_128_cbc(), NULL, key, iv);
  EVP_CIPHER_CTX_init(d_ctx);
  EVP_DecryptInit_ex(d_ctx, EVP_aes_128_cbc(), NULL, key, iv);

  return 0;
}

unsigned char *aes_encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext, int *len)
{
  int c_len = *len + AES_BLOCK_SIZE, f_len = 0;
  unsigned char *ciphertext = (unsigned char *)malloc(c_len);
  EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL);
  EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len);
  EVP_EncryptFinal_ex(e, ciphertext+c_len, &f_len);
  *len = c_len + f_len;
  return ciphertext;
}

unsigned char *aes_decrypt(EVP_CIPHER_CTX *e, unsigned char *ciphertext, int *len)
{
  int p_len = *len, f_len = 0;
  unsigned char *plaintext = (unsigned char*)malloc(p_len);
  EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL);
  EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len);
  EVP_DecryptFinal_ex(e, plaintext+p_len, &f_len);
  *len = p_len + f_len;
  return plaintext;
}

void main()
{
    unsigned char * data_to_encrypt = (unsigned char*)"aaaaaaaaabbbbbbbbbbbbbbccccccccc";
    unsigned char *key_data = (unsigned char *)"aaaaaaaaaaaaaaaa";
    int key_data_len = strlen((const char*) key_data);
    char * ciphertext;
    char * plaintext;

    aes_init(key_data, 16, NULL, &Encrypt_Context, &Decrypt_Context);

    int length = strlen((const char*) data_to_encrypt)-1;

    printf("Clear text :%s\n", data_to_encrypt);

    ciphertext = (char *)aes_encrypt(&Encrypt_Context, data_to_encrypt, &length);
    printf("Crypted text :%s\n", ciphertext);

    plaintext = (char *)aes_decrypt(&Decrypt_Context, (unsigned char*)ciphertext, &length);
    printf("Decrypted text :%s\n", plaintext);
}

With this code i getting in console:

Clear text :aaaaaaaaabbbbbbbbbbbbbbccccccccc Crypted text :°ЁТ☼#єз▬├^^,♦Ёфм:ЇъШ╙y╒КzukЩu@8¤═══════════════¤¤¤¤ Decrypted text :aaaaaaaaabbbbbbbbbbbbbbcccccccc☺¤¤¤¤

What is ═══════════════¤¤¤¤ in the end of crypted text and ☺¤¤¤¤ in the end of decrypted? What's wrong with my code?

Thanks!

Upvotes: 1

Views: 2619

Answers (3)

0xC0000022L
0xC0000022L

Reputation: 21259

Most encryption algorithms will pad the data before encryption in order to make sure one cannot deduce information from the exact length of the encrypted message. Some tools even add compression before encrypting the data (followed by padding).

So the long string of uniform characters is likely padding.

The remainder likely means that you see some uninitialized data. That means the buffer you give isn't filled with zeros after the actual message so you may be encrypting garbage along the way. Or, when decrypting, you do not zero-terminate what you expect to be a string at the point the decrypted data stops.

Upvotes: 0

dirkgently
dirkgently

Reputation: 111120

ciphertext and plaintext are not C-style strings. They are mere pointers to an array of unsigned chars. The %s specifier in printf requires a null-terminated string in order to print. You have two choices:

  • Make sure that both ciphertext and plaintext are null-terminated
  • Loop over the array (since you know their lengths) and print each character individually

Typically, all such byte-strings in cryptography use hexadecimal, so, you will probably be better off with the latter.

Upvotes: 3

user784668
user784668

Reputation:

The encryption routines deal with binary data, not with C strings, the arrays they're returning pointers to are not null-terminated, so when printing with printf (which expects a null-terminated string) you're getting random garbage that happens to be located right after these arrays.

To solve this, ensure null-termination, use something like fwrite or iterate over the characters in order to print the arrays.

Upvotes: 3

Related Questions