AES encrypt / decrypt

I’m sure I’m doing the decoding and the decryption wrongly, but I don’t know what exactly.

#include "AES.h"
#include "Base64.h"

AES aes;

byte key[] = {0x7e, 0x4e, 0x42, 0x38, 0x43, 0x63, 0x4f, 0x4c, 0x23, 0x4a, 0x21, 0x48, 0x3f, 0x7c, 0x59, 0x72};

// The unitialized Initialization vector
byte iv[N_BLOCK] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

// Our message to encrypt. Static for this example.
String msg = "{\"data\":{\"value\":300}, \"SEQN\":700 , \"msg\":\"IT WORKS!!\" }";

uint8_t generate_random_unit8()
{
  uint8_t really_random = *(volatile uint8_t *)0x3FF20E44;
  return really_random;
}

// Generate a random initialization vector
void generate_iv(byte *vector)
{
  for (int i = 0; i < N_BLOCK; i++)
  {
    vector[i] = (byte)generate_random_unit8();
  }
}

void encrypt()
{
  char b64data[200];
  byte cipher[1000];
  byte iv[N_BLOCK];

  generate_iv(iv);

  base64_encode(b64data, (char *)iv, N_BLOCK);
  String IV_base64 = String(b64data);
  Serial.println(" IV b64: " + IV_base64);

  int b64len = base64_encode(b64data, (char *)msg.c_str(), msg.length());

  Serial.println(" The lenght is:  " + String(b64len));

  // Encrypt! With AES128, our key and IV, CBC and pkcs7 padding
  aes.do_aes_encrypt((byte *)b64data, b64len, cipher, key, 128, iv);

  Serial.println("Cipher size: " + String(aes.get_size()));

  base64_encode(b64data, (char *)cipher, aes.get_size());
  Serial.println("Encrypted data in base64: " + String(b64data));

  decrypt(b64data, IV_base64, aes.get_size());
}

void decrypt(String b64data, String IV_base64, int size)
{
  char data_decoded[200];
  char iv_decoded[200];
  byte out[200];
  char temp[200];
  b64data.toCharArray(temp, 200);
  base64_decode(data_decoded, temp, b64data.length());
  IV_base64.toCharArray(temp, 200);
  base64_decode(iv_decoded, temp, IV_base64.length());
  aes.do_aes_decrypt((byte *)data_decoded, size, out, key, 128, (byte *)iv_decoded);
  char message[msg.length()];
  base64_decode(message, (char *)out, b64data.length());
  printf("Out %s \n", message);
}

void setup_aes()
{
  aes.set_key(key, sizeof(key)); // Get the globally defined key
}

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  encrypt();
  delay(1000);
}

The decoded message should be

{"data":{"value":300}, "SEQN":700 , "msg":"IT WORKS!!". }

However I’m getting

{"data":{"value":300}, "SEQN":700 , "msg":"IT WORKS!!" }�������������������������.

I would assume that the char length is not correct?

Which AES and Base64 libraries are you using?

and

  1. Why are you using String rather than char arrays? Using String makes you go through a lot of contortions that are not needed.
  2. I see no padding applied to the cleartext before encryption. This means your cleartext length must be an exact multiple of the AES block size.
  3. Why are you using the cleartext mes.length() inside your decrypt() method. Surely it should be deduced from the b64data parameter.
  4. Why are you not using the base64 encoded length obtained from the base64_encode() method.
  5. Why are you not using the base64 decoded length obtained from the base64_decode() method.

Taken together points 2 through 5 could easily cause your symptoms.

OK, I will try to use char directly instead of String. The reason I'm not using the length obtained from the base64 is because I would get encrypted and encoded messages directly from the server and the length information will not be passed. But I see your point.

So why are you bothering with Base64 then?

You think I should pass the the cipher and the iv without encoding?

ivchoyyyy:
You think I should pass the the cipher and the iv without encoding?

If the ciphertext coming from the server is Base64 encoded then you need to Base64 decode it. If not then you don't ! You need to establish this before you go any further.

Also, you need to establish what padding has been applied to the cleartext before encryption since you will have to remove the padding after decryption

OK, thank you very much!