How and where do I use an encryption library?

Hello all!,

I am working on a program that will receive and save string passwords ( converted into chars) into EEPROM. I would like to used an encryption library, but after looking online I don't know how the start or used pre-made libraries.

Can anyone guide me to tutorials or guides on how to used encryption libraries?

After encrypting the passwords, will I still be able to save them to EEPROM? ( my circuit is not designed to have a battery connected, it simply runs and receives passwords once it is connected to the Serial Monitor).

Thank you!

-Englishcone

It's best to use one-way encryption on passwords. That way they can never be de-crypted. That sounds weird, like how do you check if it's the right password without de-crypting it? But it works. It works so well that if anyone stole your EEPROM, they would not be able to extract the passwords.

The trick is you take a password from the input and encrypt it using your algorithm. Then compare that to the stored encrypted copy. If they match, then the correct password was entered. If they don't match, there's no clue given on how to make a closer guess to the real password.

There's a bunch of encryption libraries for Arduino. I've only used two-way ones, but I expect there are some good ones out there for passwords. What did you find with Google? What was the closest one and what do you want to do different to that one?

There are two points.

  1. As mentioned by MorganS, store an encrypted version. This is (usually) not done using encryption but using a hash; search for SHA, to my knowledge, there is an Arduino library for this.
  2. Transmission of a password over a 'line'; if you don't want somebody to find the password by sniffing the 'line', you encrypt at the one side before transmission and decrypt at the other side after reception. Search terms RSA, AES and 3DES; RSA might be too heavy for an Arduino. Not sure if there is a RSA library but there are AES and 3DES Arduino libraries.

In advance of selecting an encryption library, it may be worth checking your needs against a few questions like the following:

  • How are the passwords transmitted to the device? (I assume you are receiving them over a serial link) Does the entry terminal have to send the passwords in plaintext, or can it perform some computations before sending? (To address sterretje‘s comment)
  • What does your device do when it correctly authenticates the password? Does it drive a digital output from your device/Arduino?
  • How critical is it that your system is “secure”?
  • Is it possible that users may get physical access to your device/hardware?
  • Do users ever need to be able to “recover” their password in plaintext?
  • How does a user select between storing a new password and testing an existing password?
  • Do you have multiple users & hence the need for multiple passwords associated with their own account usernames?

As MorganS & sterretje suggested, it is very likely that a cryptographic hash algorithm, such as SHA1, can be a useful part of your solution, but it depends on what your system requires (questions above). When using a hash function it is very important that you “salt” it, which basically means that you combine/concatenate some additional text (possibly even the username) with the password before computing the hash. This tiny step helps significantly against certain types of password "attacks".

There are a number of cryptographic hash libraries available. Here is one fork that includes SHA1 (as an example): Cryptosuite

Assuming you are accepting a plain text password from the serial port (and decide to use a "SHA1" hash), then a simplified version of the operation can be along these lines:

  • Administrator takes the master password, computes the hash (see below) and saves the message digest to the EEPROM. This is the target hash value.
  • Capture plaintext password character string over serial, store in local buffer
  • Concatenate a "salt" string to the password string
  • Feed the salted password string into the hash function, eg.: Sha1.print(...)
  • Read back the hashed value (the test "message digest") into a byte buffer, eg. Sha1.result()
  • Read the previously stored hashed value (the target digest) from the EEPROM
  • Compare the two 20-byte message digests to ensure they are an exact match

Thank you for all the help. I will definitely need to do some research.

Right now, the project is run from a Nano on a keychain. (drilled a hole straight down, for a keyring).

The idea I had is to use a master password to access all EEPROM saved passwords, in plain text. When a new password is given, that is encrypted and added to EEPROM. All I need is for the passwords to be encrypted into EEPROM, which is my problem. Since EEPROM saves in bytes, do I have to split the encrypted password into bytes?

I tried splitting the saved password into bytes by saving each as separate chars in EEPROM, but of course this has no security. Someone could take my key chain, run EEPROM read, convert from ASCII encoding, and my passwords are accessed. How should I save these passwords in EEPROM?

Does anyone know of tutorials about using encryption libraries? As a beginner, I can't do anything with a downloaded library without instructions.

Thank you!

-Englishscone

Right now, I've been trying to make / or download a two way encryption technique. Making a encryption method isn't really working, and my noob skills would probably create weak security, so I've thought about using a library.

Does anyone know of tutorials about using encryption libraries?

Just pick a library, like AES, and experiment with the examples (scroll down the page to see "usage example").

Be sure to use Serial.print(character, HEX) to see the hexadecimal equivalent of an encrypted character, as many of them will not be printable.

I've fixed the first example in the above library, posted below:

#include "AESLib.h"

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
uint8_t key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
char data[] = "0123456789012345"; //16 chars, 17 bytes including zero terminator
aes128_enc_single(key, data);
Serial.print("encrypted:");
for (byte i=0; i<16; i++) {
  Serial.print(data[i]&0xFF,HEX);
  Serial.print(" ");
}
Serial.println();
aes128_dec_single(key, data);
Serial.print("decrypted:");
Serial.println(data);
}

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

}

Thank you very much!

I just tried the example, it worked great. It seems powerful and quick. To protect the values long term, am I able to save the encrypted values into eeprom and then uncover them after reading and deciphering them from eeprom?

Is there a better way I should do this?

I am a complete beginner to all this, thank you so much for your help.

-Englishscone

am I able to save the encrypted values into eeprom

Yes. Google "arduino eeprom" for info.

Is there a better way I should do this?

Whatever works for you is a fine way, but better in what way?

jremington:
Yes. Google "arduino eeprom" for info.
Whatever works for you is a fine way, but better in what way?

When I run the encryption example above, the encrypted values I want to save don't appear to be bytes, the only thing I can save in eeprom. Can I convert these values somehow?

Sincerely,

-Englishscone

uint8_t and char are both 8-bit wide variables. They can be stored in a byte with no loss of precision.

Look at the EEPROM reference for put(). That writes any datatype to EEPROM. But you still need to know how big your data is. If you put() a 2-byte int in location 1, you can't put anything in location 2.

MorganS:
uint8_t and char are both 8-bit wide variables. They can be stored in a byte with no loss of precision.

Look at the EEPROM reference for put(). That writes any datatype to EEPROM. But you still need to know how big your data is. If you put() a 2-byte int in location 1, you can't put anything in location 2.

Thank you! This helps. I'll see what I can come up with to save these values.

MorganS:
uint8_t and char are both 8-bit wide variables. They can be stored in a byte with no loss of precision.

Look at the EEPROM reference for put(). That writes any datatype to EEPROM. But you still need to know how big your data is. If you put() a 2-byte int in location 1, you can't put anything in location 2.

Please correct me if I'm wrong, so these password chars will be one byte, and I won't need to add spacing in the eeprom addresses?

Spacing? Just cycle through the array and store the bytes in sequential addresses.

MorganS:
Spacing? Just cycle through the array and store the bytes in sequential addresses.

Thank you I'll try!

I am most likely about to start programming with this plan in mind:

1: convert passwords into chars

2: encrypt chars using the library and saved them into eeprom

3: read the encrypted chars from eeprom and run the decrypt library function on them

4: print readable, decrypted chars

Should this work?

One of my concerns was monitoring the last used eeprom address. I had before saved the address as an int in eeprom address 0, but I heard with a byte I can only store a number up to 255. Do I need to compress this number somehow, or use 2 addresses to saved the last used address?

Sincerely,

-Englishscone

Use two EEPROM bytes to save the last used address.

Thank you! I'm sorry, how do I do that?

Did you overlook the suggestion in reply #11?

jremington:
Did you overlook the suggestion in reply #11?

Oh eeprom put! Thank you very much let me try this...

Originally, the last used address was saved at zero using EEPROM write, so now it will be saved at addresses 0 and 1.

When I'm reading this value, do I call the first address value like this to get the whole value?:

int whole_address_number = EEPROM.read(0);

Sincerely,

-Englishscone