3

Okay, here's the story. I'm not very familiar with how Arduino works but learning. I have a project that requires AES encryption on the Arduino Uno. As per a previous question we managed to figure out the problem but failed to resolve it fully so we started using another library. (This one: https://github.com/qistoph/ArduinoAES256)

uint8_t key[] = { // 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f };

Now onto the problem itself. Using an online AES encryption tool such as: http://aesencryption.net/ Simply asks for a Key of the encryption in plain text and the output is base64 as specified by the service here: The result of the encryption will appear in base64 encoded to prevent character encoding problems. Also, plain text can be used to process the encryption using AES algorithm.

I've been trying to achieve the exact same result using an Arduino Uno board with the exact same requirements. The end result is to have a base64 string that can be decrypted on another remote location having the same key.

Now as for the .ino file it has this setup:

#include "aes256.h" //Include library files
#define DUMP(str, i, buf, sz) { Serial.println(str); \
    for(i=0; i<(sz); ++i) { if(buf[i]<0x10) Serial.print('0'); Serial.print(char(buf[i]), HEX); } \
    Serial.println(); } //Help function for printing the Output

aes256_context ctxt;

void setup() {
  int i;
  Serial.begin(9600);

  Serial.println("Initializing AES256... ");
  uint8_t key[] = { //
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
  };
  DUMP("Key: ", i, key, sizeof(key));
  aes256_init(&ctxt, key);

  uint8_t data[] = { //"asdfasdfasdfasdf"
    0x61, 0x73, 0x64, 0x66, 0x61, 0x73, 0x64, 0x66,
    0x61, 0x73, 0x64, 0x66, 0x61, 0x73, 0x64, 0x66
  };
  DUMP("Unencrypted data: ", i, data, sizeof(data));

  aes256_encrypt_ecb(&ctxt, data);
  DUMP("Encrypted data: ", i, data, sizeof(data));

  aes256_decrypt_ecb(&ctxt, data);
  DUMP("Back decrypted data: ", i, data, sizeof(data));

  aes256_done(&ctxt);
}

void loop() {
}

1) I can't seem to understand what is required to have a plain text key and plain text message to encrypt giving an end result of base64 output.

For example if I were to do this using JavaScript: (And this is just an example).


2) I'd like to achieve something like this:

var key = "32 characters plain text here";
var plain = "Unlimited characters text here that can be used by the library to encrypt this plain message variable";
var base64_output = aes.encrypt256(key, plain);

3) I'd like to have the base64_output as base64 string so that it can be printed on a third-party printer hooked to the Arduino. - Is this impossible to achieve? We've been trying for some time now from endless conversions to splitting up our plain text into chunks of 16 characters so that we can encrypt the message.


Any help is greatly appreciated. If someone doesn't mind us contacting them over the phone we would also greatly appreciate a phone call to have this issue explained and resolve so we can share our experience with the Arduino community.

Thanks in advance.

edit:

We're getting this error enter image description here

edit2:

Thank you @Nick Gammon for the quick response. After removing const from the function 4 places and the key variable declaration, everything seems to be working fine now. We modified the code in order to print all bytes for each cipher block. We have this output:

140 145 154 38 228 66 98 128 116 68 245 193 70 84 205 115 
Œ‘š&äBb€tDõÁFTÍsŒ‘š&äBb€tDõÁFTÍs
186 174 17 21 162 83 96 210 128 134 46 206 172 215 0 103 
º®¢S`Ò€†.ά×
112 4 216 150 27 202 6 176 77 159 123 231 127 128 32 132 
pؖʰMŸ{ç€ „pؖʰMŸ{ç€ „
215 110 118 33 167 193 212 121 156 46 63 139 183 124 63 152 
×nv!§ÁÔyœ.?‹·|?˜×nv!§ÁÔyœ.?‹·|?˜
130 91 174 118 4 202 250 74 228 7 173 40 246 124 53 173 
‚[®vÊúJä­(ö|5­‚[®vÊúJä­(ö|5­
231 48 204 82 235 172 202 139 33 134 137 81 209 191 210 217 
ç0ÌRë¬Ê‹!†‰QÑ¿ÒÙç0ÌRë¬Ê‹!†‰QÑ¿ÒÙ
184 161 98 135 12 230 86 213 183 113 103 234 187 213 224 133 
¸¡b‡æVÕ·qgê»Õà…¸¡b‡æVÕ·qgê»Õà…
Done

We're trying to convert each array of bytes into a char array of hex values then base_64 encode it. But we're getting this output which is not what we want. Can you please explain how can we achieve this. Please let us know if it is possible to open a chat with you so that we can understand this better.

8
  • What is stopping you? Is it the conversion of the encrypted string to base-64?
    – JRobert
    Jul 14, 2015 at 23:47
  • Well for starters I am unable to do a simple plain text conversation such as the silly JavaScript example above for the key and plain variables and convert them to uint8_t arrays of hex. Among other issues described above. Jul 14, 2015 at 23:54
  • 1
    What I'm asking, more specifically, is: what have you tried; what were you expecting to happen; and what actually did happen?
    – JRobert
    Jul 14, 2015 at 23:55
  • @JRobert 1, The lack of documentation out there for implementing AES properly on Arduino devices. And 2, Converting a string such as String plain = "Hello World" into a uint8_t array. Jul 14, 2015 at 23:58
  • We've been trying for some time now from endless conversions to splitting up our plain text into chunks of 16 characters so that we can encrypt the message. - I'm a little confused as to why that is a problem. Can you show your attempts to break your string of text into groups of 16 bytes? I'm thinking: a for loop - what are you thinking?
    – Nick Gammon
    Jul 15, 2015 at 4:47

3 Answers 3

1

We've been trying for some time now from endless conversions to splitting up our plain text into chunks of 16 characters so that we can encrypt the message.

To address this question/issue, below is some code that will take an arbitrary length string and break it into 16-character strings suitable for encoding with AES:

const int KEY_SIZE = 32;
const int BLOCK_SIZE = 16;
const char message [] = "Unlimited characters text here that can be used by the library to encrypt this plain message variable";
const byte key [KEY_SIZE] = "32 characters plain text here";

void encrypt_it (const byte plaintext [BLOCK_SIZE], const byte cipherkey [KEY_SIZE]);  // prototype
void encrypt_it (const byte plaintext [BLOCK_SIZE], const byte cipherkey [KEY_SIZE])
  {
  // encrypt here
  }

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

  const char * p = message;

  while (strlen (p) > 0)
    {
    byte plain [BLOCK_SIZE];
    memset (plain, 0, BLOCK_SIZE);  // ensure trailing zeros
    // copy block into plain array
    memcpy (plain, p, min (strlen (p), BLOCK_SIZE));
    // encrypt it
    encrypt_it (plain, key);
    // advance past this block
    p += min (strlen (p), BLOCK_SIZE);
    }
  Serial.println ("Done");
  }  // end of setup

void loop ()
  {
  }  // end of loop

I'd like to have the base64_output as base64 string so that it can be printed on a third-party printer hooked to the Arduino. - Is this impossible to achieve?

Of course it is possible. Just look up (Google) a C or C++ function to base-64 encode a string. There must be thousands of them. This is not an Arduino question, this is a C programming question.


As per a previous question we managed to figure out the problem but failed to resolve it fully ...

Namely here: Implementing DES or AES Encryption with DateTime Synchronization on Uno.

This question actually looks remarkably similar to your previous one.

4
  • please check our edit on the post. It shows the error that we are getting when trying to implement aes encryption according to your method. Thank you Jul 16, 2015 at 22:06
  • You can copy and paste error messages you know (the text of them). You don't have to take screenshots. Change const byte on the function encrypt_it to byte (4 places).
    – Nick Gammon
    Jul 16, 2015 at 22:19
  • sorry for uploading a screenshot. We implemented the changes and updated our post. Appreciate if you can take a look at it again. Thanks in advance Jul 16, 2015 at 23:06
  • The reason of this conversion is to decode it online using this website which takes a base_64 encoded string. aesencryption.net Jul 16, 2015 at 23:10
1

2) I'd like to achieve something like this:

var key = "32 characters plain text here"; var plain = "Unlimited characters text here that can be used by the library to encrypt this plain message variable"; var base64_output = aes.encrypt256(key, plain);

So do it.

#define MAX_MESSAGE_SIZE 256
uint8_t key[] = "32 characters plain text here";
uint8_t plain[MAX_MESSAGE_SIZE+1] = "Unlimited characters text here that can be used by the library to encrypt this plain message variable";
aes256_init(&ctxt, key);
aes256_encrypt_ecb(&ctxt, plain);
// plain is now encrypted.

That is limited to a maximum message (and encrypted output) size of 256 bytes due to the (purely arbitrary) size of the array I chose.

3
  • I think unlimited is an unwise word to use considering that the Arduino Uno has 2 KB of RAM.
    – Nick Gammon
    Jul 15, 2015 at 10:27
  • @NickGammon Not my word - copied and pasted from the question. Like the universe - "Infinite but bounded" - what does it really mean? Unlimited as long as it's less than the maximum number of characters allowed by the array ;) - as noted in the "That is limit to ..." paragraph.
    – Majenko
    Jul 15, 2015 at 10:29
  • I realize it isn't your word. It is the OP's word. :)
    – Nick Gammon
    Jul 15, 2015 at 10:44
0

If you don't have to have the features of the String object, I'd highly recommend you use a uint8_t (or 'byte' or 'char') array from the get-go. It avoids the conversion altogether, as well as the code complexities of dealing with Strings.

uint8_t plain = "Hello World"; works great for a literal string, or if you need more flexibility, uint8_t plain[256+1] = "Hello World"; lets you use or re-use that space for whatever strings you need to hold at run-time (pick a size appropriate for your needs, obviously). Will that let you get past the conversion road-block to focus on encryption (about which, I'd be no help at all).

2
  • How will uint8_t plain = "Hello World"; be equal to this? uint8_t key[] = { // 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f }; Given that Hello World` will change based on keyboard input? Jul 15, 2015 at 0:41
  • I think you mean uint8_t plain[] = "Hello World" - you forgot the array notation []
    – Majenko
    Jul 15, 2015 at 9:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.