After trying and testing several encryption libraries, I finally found one that could be implemented in a way that would allow encryption and decryption of a byte array of any size (tested to an array with 255 characters). Encryption using Spaniakos - AES Encryption Library for Arduino and Raspberry Pi. Download library from: https://github.com/spaniakos/AES/archive/master.zip See also: https://spaniakos.github.io/AES/index.html https://www.arduinolab.net/aes-encryptiondecryption-using-arduino-uno/
// Encryption example using Spaniakos - AES Encryption Library for Arduino and Raspberry Pi. // Example created by: Mark W Kiehl Mechatronic Solutions LLC // Example provided "as-is" without any warranty or implied fitness for use. ////////////////////////////////////////////////////////////////////////////// // Encryption using Spaniakos - AES Encryption Library for Arduino and Raspberry Pi // Download library from: https://github.com/spaniakos/AES/archive/master.zip // https://spaniakos.github.io/AES/index.html // https://www.arduinolab.net/aes-encryptiondecryption-using-arduino-uno/ #includeAES aes; byte *key = (unsigned char*)"01234567890123456789012345678901"; // encryption key unsigned long long int myIv = 36753562; // CBC initialization vector; real iv = iv x2 ex: 01234567 = 0123456701234567 byte iv [N_BLOCK] ; unsigned long successCount = 0; boolean bVerbose = false; // You must define arrays for encryption / decryption here globally // if you intend to populate the contents of strToEncrypt in a loop // where the contents change (such as sensor data). // Define arrays for encryption byte iSizeUnpadded = 111; byte iSizePadded = 113; // =iSizeUnpadded+17 works for any size. See setup() for calculation of exact padding. byte arrToEncrypt[111]; // Size = iSizeUnpadded byte cipher[113]; // Encrypted arrToEncrypt. Size = iSizeUnpadded + 17 // Define arrays for decryption byte arrDecryptedPadded[113]; // decrypted cipher with padding. Size = iSizeUnpadded + 17 byte decrypted[111]; // decrypted string without padding. Size = iSizeUnpadded ////////////////////////////////////////////////////////////////////////////// const byte pinBuiltInLED = 13; void setup() { pinMode(pinBuiltInLED, OUTPUT); Serial.begin(9600); while (!Serial) { delay(1); } Serial.println("Serial ready\n"); // declare and initialize the variables for encryption / decryption aes.iv_inc(); // Use the statement below to calculate the exact size for iSizePadded Serial.print("iSizePadded = "); Serial.println(sizeof(arrToEncrypt) + (N_BLOCK - ((sizeof(arrToEncrypt)-1) % 16))); } // setup() void loop() { digitalWrite(pinBuiltInLED, HIGH); // Fill arrToEncrypt with random content with a length between 5 and iSizeUnpadded byte iSizeArr = random(5,iSizeUnpadded); BuildRandomChar(arrToEncrypt, iSizeArr); int iSizePadded = iSizeArr + (N_BLOCK - ((iSizeArr-1) % 16)); // length of padded arrToEncrypt if (iSizePadded > sizeof(cipher) || iSizePadded > sizeof(arrDecryptedPadded)) { Serial.print("ERROR - array size of cipher or arrDecryptedPadded is too small!"); while (1); } // Encrypt arrToEncrypt and update cipher with the result aesEncrypt(256, bVerbose); // Decrypt cipher, and update decrypted with the result aesDecrypt(256, bVerbose); // Compare arrToEncrypt to decrypted int matches = 0; for(int i=0; i < iSizeUnpadded; i++){ if(arrToEncrypt[i]==decrypted[i]){ matches++; } } if (matches == sizeof(arrToEncrypt)) { successCount++; digitalWrite(pinBuiltInLED, LOW); } Serial.print(matches/sizeof(arrToEncrypt)*100); Serial.print("% match between arrToEncrypt and decrypted for size = "); Serial.print(iSizeArr); Serial.print(" bytes ( encrypt/decrypt count = "); Serial.print(successCount); Serial.println(") "); if (matches == sizeof(arrToEncrypt)) { successCount++; } else { Serial.print("ERROR after "); Serial.print(successCount); Serial.println(" encrypt/decrypt cycles"); Serial.print("sizeof(arrToEncrypt) = "); Serial.println(sizeof(arrToEncrypt)); Serial.print("matches = "); Serial.println(matches); for(int i=0; i < sizeof(arrToEncrypt); i++){ Serial.print(i); Serial.print(",0x"); Serial.print(arrToEncrypt[i],HEX); Serial.print(",0x"); Serial.println(decrypted[i],HEX); } while (1); } Serial.println(); } // loop() ////////////////////////////////////////////////////////////////////////////// // Encryption using Spaniakos - AES Encryption Library for Arduino and Raspberry Pi void aesDecrypt(int bits, boolean bVerbose) { // Decrypt cipher and write to arrDecryptedPadded aes.set_IV(myIv); aes.get_IV(iv); unsigned long us = micros(); //Serial.print("aesDecrypt aes.get_size() = "); Serial.println(aes.get_size()); aes.do_aes_decrypt(cipher,iSizeUnpadded+1,arrDecryptedPadded,key,bits,iv); if (bVerbose == true) { Serial.print("Decryption took "); Serial.print(micros() - us); Serial.println(" us"); } // Create new array decrypted with the unencrypted content // from arrDecryptedPadded excluding the padding. for (int i=0; i < iSizeUnpadded; i++) { decrypted[i] = arrDecryptedPadded[i]; } } // aesDecrypt() void aesEncrypt(int bits, boolean bVerbose) { // Encrypts arrToEncrypt based on bits (256) bit encryption and updates // cipher with the encrypted result. aes.set_IV(myIv); aes.get_IV(iv); unsigned long us = micros (); //Serial.print("aesEncrypt aes.get_size() = "); Serial.println(aes.get_size()); aes.do_aes_encrypt(arrToEncrypt,iSizeUnpadded+1,cipher,key,bits,iv); if (bVerbose == true) { Serial.print("Encryption took "); Serial.print(micros() - us); Serial.println(" us"); } } // aesEncrypt() ////////////////////////////////////////////////////////////////////////////// void BuildRandomChar(byte *arr, int len){ byte j = 0; for (int i=0; i < len-1; i++) { switch (j){ case 0: arr[i] = char(random(65,91)); j = 1; break; case 1: arr[i] = char(random(97,123)); j = 2; break; default: arr[i] = char(random(48,58)); j = 0; break; } // switch } arr[len-1] = 0x00; } // BuildRandomChar()
Do you need help developing or customizing a IoT product for your needs? Send me an email requesting a free one hour phone / web share consultation.
The information presented on this website is for the author's use only. Use of this information by anyone other than the author is offered as guidelines and non-professional advice only. No liability is assumed by the author or this web site.