Link to home
Start Free TrialLog in
Avatar of Stealthrt
StealthrtFlag for United States of America

asked on

AES encryption to decryption not outputting correctly

Hey all I am having the hardest time trying to figure out how to go about the order of decryption the encrypted text.

This is my sketch code:

#include "AES.h"
#include "base64.h"

AES aes;

void gen_iv(byte  *iv) {
    for (int i = 0 ; i < N_BLOCK ; i++ ) {
        iv[i]= (byte) *(volatile uint8_t *)0x3FF20E44;
    }
}

void setup() {
  Serial.begin(115200);
    Serial.println("\nBooting...");  

    char b64data[2000];
    byte cipher[1000];
    byte iv [N_BLOCK];
    char *encodedFinal;

    Serial.println("Let's encrypt:");

    byte *key = (unsigned char*)"5TGB&YHN7UJM(IK<";
    byte *my_iv = (unsigned char*)"!QAZ2WSX#EDC4RFV";
    char *msg = "{\"data\":{\"value\":300}, \"SEQN\":700 , \"msg\":\"IT WORKS!!\" }";

    //Set the key for AES
    aes.set_key(key, sizeof(key));

    /*
    ==================================================================
    Encoding section
    ==================================================================
    */

    //Encode IV to Base64
    base64_encode(b64data, (char *)my_iv, N_BLOCK);    
    Serial.println("      IV -> Base64: " + String(b64data));
    Serial.println("       Orignal Msg: " + String(msg));

    //Encode message into Base64
    int b64len = base64_encode(b64data, (char *)msg, String(msg).length());
    Serial.println(" Message -> Base64: " + String(b64data));

    // Encrypt into AES256   
    aes.do_aes_encrypt((byte *)b64data, b64len , cipher, key, 256, my_iv);
    Serial.println("Encrypted: " + String(b64data));

    //Encode everything now in Base64
    base64_encode(b64data, (char *)cipher, aes.get_size());
    Serial.println("Encrypted -> Base64: " + String(b64data));
    encodedFinal = (char*)b64data;
    Serial.println("Final encoded: " + String(encodedFinal));

    /*
    ==================================================================
    Decoding section
    ==================================================================
    */

Serial.println();
  Serial.println();
    Serial.println();
      Serial.println();
    //Decoding everything from Base64
    char b64dataDecode[2000];
    byte cipherDecode[1000];

    //Decode from Base64 to Encrypted msg
    base64_decode(b64dataDecode, (char *)encodedFinal, aes.get_size());
    Serial.println(" Base64 -> Encrypted: " + String(b64dataDecode));

    //Decoding from Encrypted
    aes.do_aes_decrypt((byte *)encodedFinal, base64_dec_len(encodedFinal, String(encodedFinal).length()), cipherDecode, key, 256, my_iv);
    Serial.println("Encrypted -> Original Msg: ") + String(encodedFinal);

    Serial.println("Done...");
}

void loop() {
  // put your main code here, to run repeatedly:

}

Open in new window


And this is the output I get:
Booting...
Let's encrypt:
IV -> Base64: IVFBWjJXU1gjRURDNFJGVg==
Orignal Msg: {"data":{"value":300}, "SEQN":700 , "msg":"IT WORKS!!" }
Message -> Base64: eyJkYXRhIjp7InZhbHVlIjozMDB9LCAiU0VRTiI6NzAwICwgIm1zZyI6IklUIFdPUktTISEiIH0=
Encrypted: eyJkYXRhIjp7InZhbHVlIjozMDB9LCAiU0VRTiI6NzAwICwgIm1zZyI6IklUIFdPUktTISEiIH0=
Encrypted -> Base64: sD9f8LnxQrlOvTODLbzXPM5wWMk6+KnpmGiowTtKswGK80+yf9DyHjjiF94TwUpP/1V4f9KsHA7+1oAmBy12Dl8Dvk/ZclFvNeNrXSwCFlU=
Final encoded: sD9f8LnxQrlOvTODLbzXPM5wWMk6+KnpmGiowTtKswGK80+yf9DyHjjiF94TwUpP/1V4f9KsHA7+1oAmBy12Dl8Dvk/ZclFvNeNrXSwCFlU=




Base64 -> Encrypted: ⸮?_⸮⸮B⸮N⸮3⸮-⸮⸮<⸮pX⸮:⸮⸮⸮h⸮⸮;J⸮⸮⸮O⸮⸮⸮8⸮⸮⸮JO⸮UxҬ⸮ր&
Encrypted -> Original Msg: 
Done...

Open in new window

As you can see above, the decryption is not working correctly. The encryption works just fine though (but i think the Encoding part is not coming out correctly since its the same as the Base64 encoding?).

Help would be great in order to solve this issue!
Avatar of Qlemo
Qlemo
Flag of Germany image

First of all, why are you encoding in Base64 that often? The only moment you should do is on transport (from sender to receiver), and there is no transport here.
Code above is odd. I think the problem is you've done 2x Base64 encode + only 1x decode, so you're never going to end up with sensible results.

Also... if your using AES encryption... why bother with any Base64 encode + decode, as this provides no useful functionality.

If you strip out all the Base64 encode + decode calls, looks like your code is working.
Avatar of btan
btan

I think you need to make your code more manageable to troubleshoot.
- Suggest you remove the Base64 for time being.
- Get small block of code on encrypt and decrypt to work first.

Make consistent data type throughout the codes (let say the below)
-unsigned char key[32]; unsigned char iv[16];
-unsigned char input [128]; unsigned char output[128];
-size_t input_len = 40; size_t output_len = 0;

Sequence the operations in pseudo and write the code
1. fill the variable named key with the 32 bytes of the AES key
2. fill iv with 16 bytes of random data for use as the Initialization Vector (IV)
3. fill input with 40 bytes of input data and zeroized the rest of input.
4. identify your block cipher mode e.g. CBC mode for AES assumes that we provide data in blocks of 16 bytes.
5. identify your padding approach e.g. We only have 40 bytes of data, so need to extend "input" to contain 48 bytes of data instead.
(Simplest is to just add zeroes to the end.)
6.  initialize the AES context with your key and then encrypt the data (with padding) to the output buffer with your iv.
- in pseudo - aes_setkey_enc( &aes, key, 256 );
- in pseudo - aes_crypt_cbc( &aes, AES_ENCRYPT, 24, iv, input, output );
7. after encrypt, the first 48 bytes of the output buffer contain the encrypted data.
(This data is only protected for confidentiality purposes.)

(if needed to send data to others) Send the length of the input data, the IV and the output buffer to the other side while protecting the integrity of those values. Usually this means making a hash over the 3 mentioned data, encrypt this hash and the AES key with the public RSA key of the other party using the PKCS#1 encrypt function.)
Avatar of Stealthrt

ASKER

@david

So how would I get the value of b64len if i never use the int b64len = base64_encode(... line?
If your doing an AES encrypt + decrypt test, then there's no requirement for b64len or any Basė4 anything.
@david

But it seems to need it passed?

AES::do_aes_encrypt(byte *plain, int size_p, byte *cipher, byte *key, int bits, byte ivl [N_BLOCK])

Open in new window

Or... you can skip Base64 + pass strlen() of string required or likely the physical length of string.

Depends on how you eventually choose to handle your data... so how you terminate strings will determine exactly how you determine real string length to pass.
@David

So should that be strlen(msg) or strlen(b64data)?
@David

Just working on the encryption:

//Encode IV to Base64
    base64_encode(b64data, (char *)my_iv, N_BLOCK);    
    Serial.println("      IV -> Base64: " + String(b64data));
    Serial.println("       Orignal Msg: " + String(msg));
               
    // Encrypt into AES256   
    aes.do_aes_encrypt((byte *)b64data, strlen(b64data), cipher, key, 256, my_iv);
    Serial.println("Encrypted: " + String(b64data));

    encodedFinal = (char*)b64data;
    Serial.println("Final encoded: " + String(encodedFinal));

Open in new window


I'm getting output of:

Booting...
Let's encrypt:
      IV -> Base64: IVFBWjJXU1gjRURDNFJGVg==
       Orignal Msg: {"data":{"value":300}, "SEQN":700 , "msg":"IT WORKS!!" }
Encrypted: IVFBWjJXU1gjRURDNFJGVg==
Final encoded: IVFBWjJXU1gjRURDNFJGVg==

So something went wrong?
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.