Stealthrt
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:
And this is the output I get:
Help would be great in order to solve this issue!
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:
}
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...
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!
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.
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.
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.)
- 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.)
ASKER
@david
So how would I get the value of b64len if i never use the int b64len = base64_encode(... line?
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.
ASKER
@david
But it seems to need it passed?
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])
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.
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.
ASKER
@David
So should that be strlen(msg) or strlen(b64data)?
So should that be strlen(msg) or strlen(b64data)?
ASKER
@David
Just working on the encryption:
I'm getting output of:
So something went wrong?
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));
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 TRIALMembers 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.