6

I've got a buffer, in which i'm adding some plain text. I want to use openssl AES encryption to encrypt the text, then decrypt it, and print it back on the screen.

Code is running with no errors.

#include <fstream>
#include <iostream>
#include <stdio.h>
#include <string>
#include <openssl/aes.h>
using namespace std;

void main()
{

// Buffers
unsigned char inbuffer[1024];
unsigned char encryptedbuffer[1024];
unsigned char outbuffer[1024];


// CODE FOR ENCRYPTION
//--------------------
unsigned char oneKey[] = "abc";
AES_KEY key; 

AES_set_encrypt_key(oneKey,128,&key);
AES_set_decrypt_key(oneKey,128,&key);

//--------------------


string straa("hello world\n");
memcpy((char*)inbuffer,straa.c_str(),13);


printf("%s",inbuffer);
//this prints out fine

AES_encrypt(inbuffer,encryptedbuffer,&key);
//printf("%s",encryptedbuffer);
//this is expected to pring out rubbish, so is commented

AES_decrypt(encryptedbuffer,outbuffer,&key);
printf("%s",outbuffer);
//this is not pringint "hello world"

getchar();

}

I am aware of the fact that once placed in the new buffers, "encryptedbuffer" and "outbuffer", they are not null terminated "\0" , but even so, by printing out the raw data, i'm only getting rubbish after the decryption, At the end of the decryption, i'm assuming the \0 should also be decrypted and therefore the printf should print corectly.

Anyone knows how to make the decyption work?

Also any idea how to print the buffers using C++ libraries, maybe cout, and not printf?

jww
  • 97,681
  • 90
  • 411
  • 885
Dani Marian Morar
  • 222
  • 1
  • 3
  • 12
  • 1
    The mechanism you're using for keys isn't correct. AES is a symmetric block algorithm, and needs a key matching the block size. A PBE-style (password-based encryption) solution will often use an appropriately sized hash digest of the password to generate a properly sized key (in this case 16-bytes). The same password hashed with the same algorithm is used on the receiver side to generate the identical symmetric key and perform the decryption. In other words, your password doesn't key the cipher; its *digest* from an algorithm known to both sides does. – WhozCraig Jan 30 '14 at 00:14
  • 2
    (1) Make `oneKey` at least 16 bytes (right now, its only 3 bytes). The extra bytes will be ignored. (2) Make `straa` exactly 16 bytes (right now its only 12 or 13 bytes). (3) Reset the key in between calls to `AES_encrypt` and `AES_decrypt`. (4) Consider switching to the `EVP_*` functions, which are easier on a beginner. See, for example, [EVP Symmetric Encryption and Decryption](http://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption) on the OpenSSL wiki. Use `EVP_aes_128_ecb()` as the cipher for an equivalent program. – jww Jan 30 '14 at 03:53
  • appreciate the clear instructions! everything seems to make more sense now! :) thank you – Dani Marian Morar Jan 30 '14 at 12:31
  • You should *not* use `AES_encrypt` and friends. You should be using `EVP_*` functions. See [EVP Symmetric Encryption and Decryption](https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption) on the OpenSSL wiki. In fact, you should probably be using authenticated encryption because it provides *both* confidentiality and authenticity. See [EVP Authenticated Encryption and Decryption](https://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption) on the OpenSSL wiki. – jww May 15 '15 at 20:18

1 Answers1

3

I notice a couple of possible issues:

  • The call to AES_set_decrypt_key uses the same key as the previous call thus overwriting the key value. To make both calls up front like that, it would be necessary to use a separate key instance. Otherwise wait to call AES_set_decrypt_key until after the encryption is done.
  • The key buffer passed to AES_set_encrypt_key needs to be 16 bytes long for the bit depth of 128. As it is, it will read 16 bytes, but the contents of those are undefined.
Mark Wilkins
  • 40,729
  • 5
  • 57
  • 110
  • adding the 'AES_set_decrypt_key' after i've done the encryption actually worked! the 'printf("%s",outbuffer);' now prints out the proper "hello world". I really appreciate the simple but efficient fix. – Dani Marian Morar Jan 30 '14 at 00:22
  • 1
    I'm glad you got it working. Note that the key buffer should still be 16 bytes. There is no guarantee that the "undefined" 12 bytes following the existing `oneKey` variable will stay unchanged between the two calls. – Mark Wilkins Jan 30 '14 at 00:47
  • 2
    @DaniMarianMorar heed Mark's warning. You key *must* be 16-bytes wide. If it isn't, the OpenSSL library will blindly access whatever is in memory following the key, which is **undefined behavior**. Think of what nasties would come from that if the thing that followed was your cipher text block. – WhozCraig Jan 30 '14 at 00:53
  • Thank you for the warnings. Are you guys saying i should set `unsigned char oneKey[] = "abc";` to `unsigned char oneKey[] = "abcdefghijklmnop";` which is 16 bytes? Will that work?, thank you once again – Dani Marian Morar Jan 30 '14 at 08:14
  • @DaniMarianMorar: That is one possibility and would be sufficient in this case to prevent undefined behavior. – Mark Wilkins Jan 30 '14 at 14:50