ESP8266 – Logging data in a backend – AES and Crypto-JS

After building, on the previous posts, the Node-Red based backend to support E2EE (End to End Encryption) so we can log data into a central server/database, from our devices securely, without using HTTPS, we need now to build the firmware for the ESP8266 that allows it to call our E2EE backend.

The firmware for the ESP8266 must gather the data that it wants to send, get or generate the current sequence number for the data (to avoid replay attacks), encrypt the data and send it to the backend.
On the backend we are using the Java script library for cryptographic functions Crypto-js, and specifically we are encrypting data with the encryption algorithm AES. So all we need is to encrypt our data with AES on the ESP8266, send it to the Node-Red Crypto-js backend, decrypt it and store it, easy right?

Not quite, let’s see why:

Crypto-js and AES:
We can see that on my Node-Red function code and testing programs I’m using something similar to the following code example:

var CryptoJS = require("crypto-js");
var message  = "Message to encrypt";
var AESKey   = '2B7E151628AED2A6ABF7158809CF4F3C';

// Encrypt
var ciphertext = CryptoJS.AES.encrypt(message, AESKey );

console.log("Cypher text in Base64: " ,  ciphertext.toString(CryptoJS.enc.base64) );

// Decrypt
var bytes  = CryptoJS.AES.decrypt(ciphertext.toString(), AESKey );
var plaintext = bytes.toString(CryptoJS.enc.Utf8);

console.log("Decrypted message UTF8 decoded: ", plaintext);

Several points regarding the above code need clarification:

The code variable AESKey the way it is used on the above example encrypt and decrypt functions isn’t really a key but a passphrase from where the real key and an initialization vector or salt value is generated (I’m using the names interchangeably, but they are not exactly the same thing except they are public viewable data that must change over time/calls).
The use for the generated key is self explanatory, but the initialization vector (IV) or salt value is used to allow that the encrypted data output to be not the same for the same initial message. While the key is kept constant and secret to both parties, the IV/salt changes between calls, which means that the above code, when run multiple times, will never produce the same output for the same initial message.

Still referring to the above code, the algorithm that generates the key from the passphrase is the PBKDF2 algorithm. More info at Crypto-js documentation. At the end of the encryption the output is a OpenSSL salted format that means that the output begins by the signature id: Salted_, followed by an eight byte salt value, and after the salt, the encrypted data.

So if we want use the API has above on the node-js/crypto-js side, we need to implement on the ESP8266 side both the AES and PBKDF2 algorithms.

I decided not to do that, first because finding a C/C++ implementation of the PBKDF2 algorithm that could be portable and worked on the ESP822 proved difficult, and second the work for porting it to the ESP8266 won’t be needed if I use a KEY/IV directly, and so I decided to use the more standard way of providing an AES key and an initialization vector for encrypting and decrypting data.

In the case of Node-JS and Crypto-JS when using an explicit key and IV the code looks like:

var CryptoJS = require("crypto-js");
var request = require('request');

// The AES encryption/decription key to be used.
var AESKey = '2B7E151628AED2A6ABF7158809CF4F3C';

// The JSON object that we want to encrypt and transmit
var msgObjs = {"data":{"value":300}, "SEQN":145 };

// Convert the JSON object to string
var message = JSON.stringify(msgObjs);

var iv = CryptoJS.enc.Hex.parse('0000000000000000');
var key= CryptoJS.enc.Hex.parse(AESKey);

// Encrypt
var ciphertext = CryptoJS.AES.encrypt(message, key , { iv: iv } );

//console.log("Cypher: ", ciphertext );
console.log("Cypher text: " ,  ciphertext.toString(CryptoJS.enc.base64) );
console.log(" ");

console.log("=============================================================================");
console.log(" ");
console.log("Let's do a sanity check: Let's decrypt: ");

// Decrypt
var bytes  = CryptoJS.AES.decrypt(ciphertext.toString(), key , { iv: iv} );
var plaintext = bytes.toString(CryptoJS.enc.Utf8);

console.log("Decrypted message UTF8 decoded: ", plaintext);

Now, with above code, where the IV is always initialized to the same value, in this case ‘0000000000000000’, we can see when running the above code several times that the output is always the same since the IV is kept constant. Also the encrypted output is now just the raw encrypted data and not the Openssl format.

So to make the above code secure we must randomize the IV value for producing an output that is always different, even from several program runs when encrypting the same source data.

As a final note, if we count the number of HEX characters on the Key string, we find out that they are 16 bytes, which gives a total of 128 key bits. So the above example is using AES128 encryption, and with default Crypto-js block mode and padding algorithms which are CBC (Chain block mode) and pkcs7.

Interfacing Crypto-js and the ESP8266:
Since we are using AES for encrypting data and decrypting data, we need first to have an AES library for the ESP8266. The AES library that I’m using is this one Spaniakos AES library for Arduino and RPi. This library uses AES128, CBC and pkcs7 padding, so it ticks all boxes for compatibility with Crypto-js…

I just added the code from the above library to my Sming project and also added this Base64 library so that I can encode to and from Base64.

The only remaining issue was to securely generate a truly random initialization vector. And while at first I’ve used some available libraries to generate pseudo-random numbers to real random numbers, I’ve found out that the ESP8266 seems to have already a random number generator that is undocumented: Random number generator

So to generate a random IV value is as easy as:

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

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

So our ESP8266 code is as follow:

Global variables declarations:
The N_Block defines the encryption block size, that for AES128 is 16 bytes.

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

// The AES library object.
AES aes;

// Our AES key. Note that is the same that is used on the Node-Js side but as hex bytes.
byte key[] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C };

// The unitialized Initialization vector
byte my_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!!\" }";


The example function ESP8266 Sming code is:

void testAES128()  {

    char b64data[200];
    byte cipher[1000];
    byte iv [N_BLOCK] ;
    
    Serial.println("Let's encrypt:");
    
    aes.set_key( key , sizeof(key));  // Get the globally defined key
    gen_iv( my_iv );                  // Generate a random IV
    
    // Print the IV
    base64_encode( b64data, (char *)my_iv, N_BLOCK);
    Serial.println(" IV b64: " + String(b64data));
       
    Serial.println(" Mensagem: " + msg );
 
    int b64len = base64_encode(b64data, (char *)msg.c_str(),msg.length());
    Serial.println (" Message in B64: " + String(b64data) );
    Serial.println (" The lenght is:  " + String(b64len) );
    
    // For sanity check purpose
    //base64_decode( decoded , b64data , b64len );
    //Serial.println("Decoded: " + String(decoded));
    
    // Encrypt! With AES128, our key and IV, CBC and pkcs7 padding    
    aes.do_aes_encrypt((byte *)b64data, b64len , cipher, key, 128, my_iv);
    
    Serial.println("Encryption done!");
    
    Serial.println("Cipher size: " + String(aes.get_size()));
    
    base64_encode(b64data, (char *)cipher, aes.get_size() );
    Serial.println ("Encrypted data in base64: " + String(b64data) );
      
    Serial.println("Done...");
}

When the above code/function is executed on the ESP8266 it outputs the following:

Let's encrypt:
 IV b64: cAFviaDMHejlteGn9/4eQQ==
 Mensagem: {"data":{"value":300}, "SEQN":700 , "msg":"IT WORKS!" }
 Message in B64: eyJkYXRhIjp7InZhbHVlIjozMDB9LCAiU0VRTiI6NzAwICwgIm1zZyI6IklUIFdPUktTISIgfQ==
 The lenght is:  76
Encryption done!
Cipher size: 80
Encrypted data in base64: /1aZRwVaw3jv+ct8HS4pCV5lThvTG70M90ARiyAsIDYMkfJE3w8F3bgxaOKVA0rX4m1Mq50VVN0u9gRw9F2gKE4r2OcY8oECv8bKT80F9pY=
Done...

And now we can feed the above Base64 IV and encrypted data to our decoding program in Node-Js using Crypto-JS:

var CryptoJS = require("crypto-js");
var request = require('request');

var esp8266_msg = '/1aZRwVaw3jv+ct8HS4pCV5lThvTG70M90ARiyAsIDYMkfJE3w8F3bgxaOKVA0rX4m1Mq50VVN0u9gRw9F2gKE4r2OcY8oECv8bKT80F9pY=';
var esp8266_iv  = 'cAFviaDMHejlteGn9/4eQQ==';

// The AES encryption/decryption key to be used.
var AESKey = '2B7E151628AED2A6ABF7158809CF4F3C';

var plain_iv =  new Buffer( esp8266_iv , 'base64').toString('hex');
var iv = CryptoJS.enc.Hex.parse( plain_iv );
var key= CryptoJS.enc.Hex.parse( AESKey );

console.log("Let's decrypt: ");

// Decrypt
var bytes  = CryptoJS.AES.decrypt( esp8266_msg, key , { iv: iv} );
var plaintext = bytes.toString(CryptoJS.enc.Base64);
var decoded_b64msg =  new Buffer(plaintext , 'base64').toString('ascii');
var decoded_msg =     new Buffer( decoded_b64msg , 'base64').toString('ascii');

console.log("Decrypted message: ", decoded_msg);

and the output is:

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

So, as the message shows, it WORKS!. AES encryption on the ESP8266 to a Node-JS Crypto-JS based code where decryption occurs.

Final notes:
So all is needed now is to build on the ESP8266 side the message with the encrypted data and the IV, and send through plain HTTP a JSON object to the Node-Red back end.

{
  "msg":"/1aZRwVaw3jv+ct8HS4pCV5lThvTG70M90ARiyAsIDYMkfJE3w8F3bgxaOKVA0rX4m1Mq50VVN0u9gRw9F2gKE4r2OcY8oECv8bKT80F9pY=",
  "iv":"cAFviaDMHejlteGn9/4eQQ=="
}

On the Node-Red back end the decryption can now be done easily as was shown on the above testing code.

Further reading:

More information also available at: ESP8266 and AES128 for end-to-end encryption and Establishing secure ESP8266 and NodeJs communication by using Diffie-Hellman key exchange and Elliptic Curves

62 thoughts on “ESP8266 – Logging data in a backend – AES and Crypto-JS

  1. Hello, Thanks for the example and detailed description. I actually wanted to do the reverse of this basically encrypting in the Node js and decrypting in the ESP8266 and use AES 256 encryption. I was trying that, but could not decrypt the message successfully at the ESP side. Not sure why though, but the reverse should be possible right ?

    Thanks for your help.

  2. I didn’t tried the reverse, but normally on IoT devices, decryption is a very expensive operation, so you can try the reverse, pick the plain message on the nodejs side, but instead of encrypting it, use the decrypt function as on my example, and on the ESP8266 side, reverse the process by encrypting. It should work.

  3. I was already using ESP8266 based sensors and Raspberry Pi with Node-Red / emoncms backend for data collection.
    With your posting I was able to encrypt the sensor data and decrypt it inside a function node of the node-red environment. Great.

  4. Just wanted to say thank you so much for writing this, I spent all day trying to find how to properly do this. How’s it feel to be a super hero? 🙂 Thanks bud

  5. Hello, Thank you very much for the Node-Red and the Crypto-JS library article. However, I’m really struggling how can I do it other way around. Can I kindly ask you write an article how can we send encrypted messages from node and decrypt them on ESP8266? I think this will be very helpful for every beginner. Thank you in advance!

    1. Hi:

      One quick solution is to do the reverse, for example on NodeJs pickup a message, let’s say “Hello Word!”, but instead of encrypting it, use the decrypt function and send it to the ESP8266. On the ESP8266, encrypt and the original message should be recovered.
      This is an hack, that is used in the real world, also, because it allows only to have one function on each side.

      1. lol, I will try it. I guess I need to pass the iv used for decryption from the server to the ESP8266 as well?

  6. For random number generation, it appears the technique you use is in the ESP8266 Arduino library.
    see:
    https://github.com/esp8266/Arduino/issues/1710
    and
    https://github.com/esp8266/Arduino/pull/2142 .
    in summary, use secureRandom(howbig) and secureRandom(howsmall, howbig) to explicitly use the HW RNG.

    as for AES on the ESP8266, there is built in AES hardware on the microcontroler (used in SSL in the SDK) but annoyingly Espressif don’t appear to have published header files or documentation on how to use it so yes, Spaniakos AES library looks like the easiest solution.

    thanks for the post; it gave me some ideas where/how to start researching this topic.

    dunk.

    1. At the time I was using the Sming framework, not the Arduino framework. Sming is more low level, so no “fancy” random functions 🙂

  7. Thank you very much for this awesome article, it is a life saviour. Although like other people i also wanted to do the reverse of it. Send encrypted message to ESP and decrypt them there.
    So as u suggested i tried to send a (Actually) decrypted message from node server. i wrote a function like the below one. but i am getting error in this saying – RangeError – Invalid array length.
    its coming in this line ” var plaintext = bytes.toString(CryptoJS.enc.Base64);”. I think which is caused due to improper bytes array. generated in this line “var bytes = CryptoJS.AES.decrypt( message, key , { iv: iv} );”.
    can u help me here or correct me what is it that i am doing wrong.

    https://pastebin.com/gHmWUbeL

  8. In function ‘void testAES128()’:
    error: ‘base64_encode’ was not declared in this scope

    base64_encode( b64data, (char *)my_iv, N_BLOCK);

    exit status 1
    ‘base64_encode’ was not declared in this scope

    I get this error although I have added Base64 Library and included it in the code.

  9. Thank you for your excellent tutorial. Is there any way to use this code for more than one variable? For example, encrypting/decrypting a value from one sensor and then encrypting/decrypting another value from a different sensor. I’ve been stuck on this for quite a while as I can only get it to encrypt/decrypt one value at a time and I keep ending up with “Invalid array length” errors from the NodeRed end for anything but the first value I encrypt/decrypt.

    1. It really depends on what you need. You can produce different messages (JSON objects) and encrypt them separately or, you can get all the sensor data, build a single JSON object (or string, whatever) with all the data, encrypt it and send it to the back end…

      So sorry, not sure what might be the problem that you are facing.

  10. Hi, I try all but i can’t. I need help you. I want encrypt but.. it’s not work:

    encryptMessage(“helloAll”)
    decryptMessage(encrypted1,ivHex) // The value of encrypted1 and ivHex, I get when I do encryptMessage

    function encryptMessage(messagePlain) {
    console.log(“———————–“)
    console.log(“—- EncryptMessage —“)
    console.log(“———————–“)

    try {
    var key = CryptoJS.enc.Hex.parse(AESKey);
    var ivPlain = “987654321098765” // generate IV
    var ivBase64 = new Buffer(ivPlain).toString(‘base64’) // ENCODE BASE 64 IV
    var ivHex = CryptoJS.enc.Hex.parse(ivBase64);
    var txtBase64 = new Buffer(messagePlain).toString(‘base64’) // ENCODE BASE 64 TEXT
    var encrypted1 = CryptoJS.AES.encrypt(txtBase64, key , { iv: ivHex });
    encrypted1.toString(CryptoJS.enc.base64)

    console.log(“encrypted1: “+ encrypted1);
    console.log(“iv1: “+ ivHex);

    // I save this information: encrypted1 and ivHex

    }catch(error) {
    console.log(“error ENCRYPT: “+error)
    }
    }

    function decryptMessage(msg, ivSEend) { // OK arduino
    console.log(“———————–“)
    console.log(“—- DecryptMessage —“)
    console.log(“———————–“)

    var plain_iv = new Buffer( ivSEend , ‘base64’).toString(‘hex’);
    var iv = CryptoJS.enc.Hex.parse( plain_iv );
    var key = CryptoJS.enc.Hex.parse( AESKey );

    // Decrypt
    var bytes = CryptoJS.AES.decrypt( msg, key , { iv: iv} )
    console.log(“bytes: “+bytes)

    try {
    var plaintext = bytes.toString(CryptoJS.enc.Base64)
    var decoded_b64msg = new Buffer(plaintext , ‘base64’).toString(‘ascii’);
    var decoded_msg = new Buffer( decoded_b64msg , ‘base64’).toString(‘ascii’);
    console.log(“Decrypt: “, decoded_msg);
    }catch(error) {
    console.log(“error DECRYPT: “+error)
    }
    }

    thx!!!!

      1. Hi,

        I’ve managed to get it to encrypt and decrypt in arduino, but in node, I can only encrypt and decrypt if I don’t add the IV, someone can help me please!!.

        [quote]
        Arduino Encrypt -> Arduino Decrypt [color=limegreen]OK[/color]
        Arduino Encrypt -> Node Decrypt [color=limegreen]OK[/color]
        Node Encrypt -> Node Decrypt [color=red]KO (fail IV)[/color]
        [/quote]

        I can’t encode the IV , for decryption works 😥

        [u]Node Encrypt -> Node Decrypt [b]With[/b] IV [color=red](fail)[/color] : [/u]

        var CryptoJS = require("crypto-js");
        var AESKey = '2B7E151628AED2A6ABF7158809CF4F3C';
        
        
        encryptMessage("helloAll")
        
        
        function encryptMessage(messagePlain) {
            console.log("-----------------------")
            console.log("---- EncryptMessage ---")
            console.log("-----------------------")
        
            try {
                var key = CryptoJS.enc.Hex.parse(AESKey);
                var ivPlain = "987654321098765"  // generate IV
               // var ivBase64 = new Buffer(ivPlain).toString('base64')    // ENCODE BASE 64 IV
                var ivHex = CryptoJS.enc.Hex.parse(ivPlain);
                var txtBase64 = new Buffer(messagePlain).toString('base64')    // ENCODE BASE 64 TEXT
                var encrypted1 = CryptoJS.AES.encrypt(txtBase64, key , { iv: ivHex });      
                encrypted1.toString(CryptoJS.enc.base64)
        
                console.log("encrypted1: "+ encrypted1);
                console.log("iv1: "+ ivHex);
        
                decryptMessage(encrypted1, ivHex)
        
        
            }catch(error) {
                console.log("error ENCRYPT: "+error)
            } 
        }
        
        function decryptMessage(msg, ivSEend) { 
            console.log("-----------------------")
            console.log("---- DecryptMessage ---")
            console.log("-----------------------")
        
            var plain_iv =  new Buffer( ivSEend , 'base64').toString('hex'); // DECODE BASE 64 IV -> transform HEX
            var iv = CryptoJS.enc.Hex.parse( plain_iv );
            var key = CryptoJS.enc.Hex.parse( AESKey );
            
            // Decrypt
            var bytes  = CryptoJS.AES.decrypt( msg, key , { iv: iv} )
            console.log("bytes: "+bytes)
            
            try {
                var plaintext = bytes.toString(CryptoJS.enc.Base64)
                var decoded_b64msg =  new Buffer(plaintext , 'base64').toString('ascii');  // DECODE BASE 64 IV
                var decoded_msg =     new Buffer( decoded_b64msg , 'base64').toString('ascii');            
                console.log("Decrypt: ", decoded_msg); 
            }catch(error) {
                console.log("error DECRYPT: "+error)
            }   
        }
        
        

        [u]Arduino encrypt -> Node decrypt [b]With[/b] IV:[/u]

        
        var esp8266_msg = '/1aZRwVaw3jv+ct8HS4pCV5lThvTG70M90ARiyAsIDYMkfJE3w8F3bgxaOKVA0rX4m1Mq50VVN0u9gRw9F2gKE4r2OcY8oECv8bKT80F9pY=';
        var esp8266_iv  = 'cAFviaDMHejlteGn9/4eQQ==';
        
        decryptMessage(esp8266_msg, esp8266_iv)
        
        function decryptMessage(msg, ivSEend) {  
            console.log("-----------------------")
            console.log("---- DecryptMessage ---")
            console.log("-----------------------")
        
            var plain_iv =  new Buffer( ivSEend , 'base64').toString('hex'); // DECODE BASE 64 IV -> transform HEX
            var iv = CryptoJS.enc.Hex.parse( plain_iv );
            var key = CryptoJS.enc.Hex.parse( AESKey );
            
            // Decrypt
            var bytes  = CryptoJS.AES.decrypt( msg, key , { iv: iv} )
            
            try {
                var plaintext = bytes.toString(CryptoJS.enc.Base64)
                var decoded_b64msg =  new Buffer(plaintext , 'base64').toString('ascii');  // DECODE BASE 64 IV
                var decoded_msg =     new Buffer( decoded_b64msg , 'base64').toString('ascii');            
                console.log("Decrypt: ", decoded_msg); 
            }catch(error) {
                console.log("error DECRYPT: "+error)
            }   
        }
        

        [u]Arduino encrypt -> Arduino decrypt [b]With[/b] IV:[/u]

        void encriptar(String message) {  // OK
           
            // IV
            String ivRandom = "1234567890123456";
            byte ivByteArray[ivRandom.length()];
            ivRandom.getBytes(ivByteArray, ivRandom.length());
        
        
            char b64dataIV[200];
            base64.b64_encode( b64dataIV, (char *)ivByteArray, N_BLOCK);
            String iv = String(b64dataIV);
            Serial.println ("IV MIO: " + iv);
        
            
            // encript message  
            int b64len = base64.b64_encode(b64data, (char *)message.c_str(),message.length()); 
            aes.do_aes_encrypt((byte *)b64data, b64len , cipher, key, 128, ivByteArray);
        
            
            // DATA encripted
            base64.b64_encode(b64data, (char *)cipher, aes.get_size() );
            String data = String(b64data);
        
            Serial.println ("Data: " + data);
        
        
            decrypt(b64data, b64dataIV, aes.get_size());
            
        }
        
        void decrypt(String b64data, String IV_base64, int lsize) {  // OK
        Serial.println("------ NEW DECRYPT ------");
          
          char data_decoded[300];
          char iv_decoded[300];
          byte out[300];
          char temp[300];
          b64data.toCharArray(temp, 300);
          base64.b64_decode(data_decoded, temp, b64data.length());
          IV_base64.toCharArray(temp, 300);
          base64.b64_decode(iv_decoded, temp, IV_base64.length());
          aes.do_aes_decrypt((byte *)data_decoded, 50, out, key, 128, (byte *)iv_decoded);
          char message[1000];
          base64.b64_decode(message, (char *)out, aes.get_size());
          for (int i = 0; i < aes.get_size(); i++)
          {
            char curChar = (char)message[i];
            if (curChar != '}')
              temp[i] = curChar;
            else
            {
              temp[i] = curChar;
              temp[i+1] = '\0';
              break;
            }
          }
          String result = String((char *)temp);
          Serial.println(result);
          Serial.println("=======");
        }
        
        
        

        Thank you very much.

      2. One of the issues might be that the representation of the IV on Arduino side is different from the nodejs side.
        So what you should do is to use a common format for the IV such as hex numbers and not strings.

      3. The Arduino Encrypt and Node decrypt communication works perfectly (including IV)

        Communication between arduino Encript -> arduino Decrypt also works

        My problem is in the encryption and description, enter node. Arduino works fine.

      4. I’m sorry, I think I’m explaining it wrong, I need the decryption function to be as it is, the problem is in the encryption.

        If I change the decryption function, Arduino code doesn’t work.
        I need to get the node encryption to work without changing the decryption.

      5. On the encrypt function change the line

        var ivHex = CryptoJS.enc.Hex.parse(ivPlain);

        to

        var ivHex = CryptoJS.enc.Base64.parse(ivPlain);

        and it works. No change on the decrypt function.

      6. ❤ You are amazing!!!, mm If you want, (when I've cleaned up all the code) I can put the code in the comments, in case people need the same case as mine.

        😀 thx!!

      7. Hi, I have to check the Arduino code decrypt because it doesn’t work 100% of the time, when I have it (if I can….) I upload it to this website.

    1. Good morning,
      I have used your code to encrypt from Arduino, and decrypt at Node and it works perfectly.

      What I need now, is to encrypt at Node and decrypt at Node without changing anything, otherwise it stops working when encrypting Arduino.

      What can I do?
      https://pastebin.com/PemccXJ1

      1. https://pastebin.com/3WmTAFkt
        this sems to work

        what i did was::

        change the dual hex of the iv to a single hex
        from:
        var plain_iv = new Buffer( ivSEend , ‘base64’).toString(‘hex’); // DECODE BASE 64 IV anda -> transform HEX
        var iv = CryptoJS.enc.Hex.parse( plain_iv );

        to:
        var iv = CryptoJS.enc.Hex.parse( ivSEend );

  11. @PrimalCortex

    I am very interested in the usage of the library , and planning to make an extension (user usability wrapper)
    can you give me some insights from your usage so far ?
    you can drop a mail at spaniakos@gmail.com if you wish.

    Thank you !

    1. Hi!,

      I think you should provide your great library as one of the available AES libraries on platformio Library registry.

      Couldn’t find it there, so to use it on Platformio based sketchs, we need to download and copy files manually.

      1. Hi!!!!

        Arduino -> Node:

        Encrypt Arduino:

        Original menssage: “{ ‘switchOnCooler’: ‘true’ }”

        data: Ww5DkZXWXN3c9QDy4iEYQwfSP8wipQXuWZgJy567ZQdt9xL40WhAyGJsAAXAldun

        iv: MTIzNDU2Nzg5MDEyMzQ1AA==

        Decrypt Node:

        { ‘switchOnCooler’: ‘true’ }

        Node -> Arduino:

        Encrypt Node:

        Original menssage: “{‘info’: ‘Hello stackoverflow’}”

        data: X6iXoxLdLItG3MmQ3Y407lwUYJW+T0Nwu7AIA5GDS+fSCK08KBycP0iNUy3x3AvU

        IV: 987654321098765

        Decrypt Arduino:

        {‘info’: ⸮⸮⸮llo stackoverflow’}

        Here in decrypt

        Thx!

      2. Does it happens with all messages from node to arduino?

        Can you try with simpler messages, just like hello?

        It seems that the message from node is sending some UTF-8 character that is not properly decoded on Arduino side.

      3. Hello,
        I’ve tried many different text strings and it always fails on one or more characters.

        Sometimes, I change a Hello -> Hallo, or similar.
        And I don’t understand what can be done. I’ve been thinking about it for weeks… and nothing

    1. Hello,
      I’ve tried many different text strings and it always fails on one or more characters.

      Sometimes, I change a Hello -> Hallo, or similar.
      And I don’t understand what can be done. I’ve been thinking about it for weeks… and nothing

      1. Hi hi!!

        Arduino code:
        https://pastebin.com/Li7tQgZg

        Base64 lib:
        https://pastebin.com/VUZEt6tz

        Message sent from Node:
        original message: ‘Prueba primalcortex’
        data: fv5nTsIs4jWAoTdhn4z8Npbw3j/9UBiz55POFya/340=
        IV: 987654321098765

        Message recived from Arduino:
        10:50:42.907 -> fv5nTsIs4jWAoTdhn4z8Npbw3j/9UBiz55POFya/340=
        10:50:42.907 -> iv:
        10:50:42.907 -> 987654321098765
        10:50:42.907 -> message:
        10:50:42.907 -> Prueba pr⸮⸮⸮lcortex

        Thank for all

      2. Hi hi!!

        Arduino code:
        https://pastebin.com/Li7tQgZg

        Base64 lib:
        https://pastebin.com/VUZEt6tz

        Message sent from Node:
        original message: ‘Prueba primalcortex’
        data: fv5nTsIs4jWAoTdhn4z8Npbw3j/9UBiz55POFya/340=
        IV: 987654321098765

        Message recived from Arduino:
        10:50:42.907 -> fv5nTsIs4jWAoTdhn4z8Npbw3j/9UBiz55POFya/340=
        10:50:42.907 -> iv:
        10:50:42.907 -> 987654321098765
        10:50:42.907 -> message:
        10:50:42.907 -> Prueba pr⸮⸮⸮lcortex

        Thank for all

      3. Hi:

        The solution here: https://github.com/fcgdam/AESCrypto_Test

        There is the ESP8266 code, and then there is a folder named Node_Code with a main.js file that sends the encrypted data with fixed IV and random IVs.

        The issue that you had was related to the improper IV decoding on the ESP side. With the Invalid IV you couldn’t decrypt properly the received data.

        That was due that the IV was sent as a string with HEX representing the bytes, so that “34” is not the same than 0x34. Hence we need to transform the received IV string from the Hex representation to the byte array.

        Take a look at the above Github repo, and it’s all there.

Leave a reply to PrimalCortex Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.