Encrypt and Decrypt RFID Tags using AESLib

I am trying to use this encryption library for RFID Tags, AESLib - Arduino Reference. I cannot find any example online or documentation that actually help me understand how to use it.
If has some reference or a working example would be nice to share :slight_smile: !

I want to decrypt RFID Tags every time I want to read from it so not anyone can read the info on it.

thinx-aes-lib/examples at master · suculent/thinx-aes-lib · GitHub

was the examples not useful for your need? If not, what is your specific use case - detailed.

Arduino "AESLib" RFID - Google Search

I need to write strings to an RFID Tag (which is already what I'm doing). But now before writing the message I want to Encrypt it then write it. After reading I decrypt the message and receive the actual string. Doing so, I will be the only person capable of decrypting the message.
In the examples I can't seem to find the encrypted message (print it at least) so that I can write to the tag.

Go to the examples linked above and look at the "simple" example. After this line:
uint16_t encLen = encrypt_to_ciphertext((char*)cleartext, msgLen, enc_iv);
You have your base64 ciphertext in the buffer named 'ciphertext'. When you get that cyphertext back from the card you do a base64_decode() on it to get the binary ciphertext and then call decrypt_to_cleartext() to recover the original message.

But how do I write the cypher text to the card? In other words, how to put the cypher text in a String variable to be able to write it.

The ciphertext is base64 encoded (converted from binary to printable characters) and in a character array, ready to be written. Write it like you would any C string.

If you want to see what the encrypted data looks like, insert this line in the "Simple" example:

  uint16_t encLen = encrypt_to_ciphertext((char*)cleartext, msgLen, enc_iv);
  Serial.print("Encrypted length = "); Serial.println(encLen );

  // INSERT THIS LINE TO SEE THE ENCRYPTED VERSION
 Serial.println(ciphertext);

  Serial.println("Encrypted. Decrypting..."); 
  Serial.println(encLen ); Serial.flush();

I tried and got the following error:
error: invalid conversion from 'unsigned char*' to 'long long unsigned int' [-fpermissive]

I'm not sure you should trust that AESlib. I installed the latest version and the "simple" example fails the decryption test:

readBuffer length: 18
Calling encrypt (string)...
Encrypted length = 44
Encrypted. Decrypting...
44
Calling decrypt...; Decrypted bytes: 44
Decrypted cleartext of length: 44
Decrypted cleartext:
#⸮C⸮⸮䡯:=a⸮⸮⸮.⸮HC⸮⸮J⸮⸮t⸮}⸮i⸮
Decryption test failed.
---

I'm not sure you should trust that AESlib.

I would not touch the Arduino AESlib library with a stick. The latest version on Github has this comment, suggesting that it never worked properly:

2.2.1 - Major decryption fix

double check GitHub - rweather/arduinolibs: Arduino Cryptography Library

The documentation contains more information on the libraries and examples.

There is a library named "Crypto" by Dr. Brandon Wiley that can encode and decode AES 128, 196, and 256 (as well as many other encryption and hashing functions). Find it in Library Manager under the name "Crypto".

Note: This library leaves your encrypted block in binary so it can't be written as a 'string'. You have to either store it as binary data or do a base64 encode on it to turn it into a string of printable text.

1 Like

it seems OP wants to store that in a RFID Tag, so binary should be fine.

Will try this approach. Thanks!

Now I have the issue that I have to read the "cypher" because this is what I v+have to decode in order to get the message. The issue is that "cypher" is a byte array. This is what you mean by using base64 encode?
I have to somehow read the cypher but I cannot write it in the form it is right now.

What RFID reader/writer are you using?
What RFID card are you using?
What RFID library are you using?

It might help if you showed your sketch.

I am using a PN532 reader (SPI Protocol) and an NFC Tag.
The library I am using are NdefMessage. The script is shown here with all details.

I am using message.addTextRecord to write to the tag as shown in the link above.

Write with:
void addMimeMediaRecord(String mimeType, byte *payload, int payloadLength);

Use mime type "application/octet-stream"

I wrote with that and it worked. But I can only do it once for some reason. I cannot encrypt, read then decrypt multiple blocks. For example:
First I encrypt:

aes128.encryptBlock(SSID_cypher, SSID_plaintext);//cypher->output block and plaintext->input block
aes128.encryptBlock(PASS_cypher, PASS_plaintext);//cypher->output block and plaintext->input block

Second I write:

message.addMimeMediaRecord("application/octet-stream", SSID_cypher, sizeof(SSID_cypher)); // Text Message you want to Record
message.addMimeMediaRecord("application/octet-stream", PASS_cypher, sizeof(PASS_cypher)); // Text Message you want to Record

Then I read and decrypt:

for (int i = 0; i < recordCount; i++)
      {
        NdefRecord record = message.getRecord(i);
        int payloadLength = record.getPayloadLength();
        byte payload[payloadLength];
        record.getPayload(payload);
case 0:
            aes128.decryptBlock(payload, SSID_cypher); 
            for(int i=0; i<sizeof(payload); i++){
              textAfterDecryption += (char)payload[i];
            }
            SSID_rfid = textAfterDecryption;
            textAfterDecryption = "";
            break;
          case 1:
            aes128.decryptBlock(payload, PASS_cypher); 
            for(int i=0; i<sizeof(payload); i++){
              textAfterDecryption += (char)payload[i];
            }
            PASS_rfid = textAfterDecryption;
            textAfterDecryption = "";
            break;
}

If I only encrypt one string it works. The switch case works as well I already wrote and read 7 blocks of strings successfully,

The output of the code above:

SSID_rfid: ␗R�5␐2摾␑�
PASS_rfid: 13151010

If I remove the following lines:

aes128.encryptBlock(PASS_cypher, PASS_plaintext);//cypher->output block and plaintext->input block

and

message.addMimeMediaRecord("application/octet-stream", PASS_cypher, sizeof(PASS_cypher)); // Text Message you want to Record

The output becomes:
SSID_rfid: TP-Link_DB0
PASS_rfid:

I guess there is a mistake somewhere in your sketch, probably in one of the parts you didn't show.

I tried the following code and managed to find the issue.

#include <Crypto.h>
#include <AES.h>
#include <string.h>
#include <Arduino.h>

String textAfterEncryption;
String textAfterDecryption;

//key[16] cotain 16 byte key(128 bit) for encryption
byte key[16]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
//SSID[16] contain the text we need to encrypt
byte SSID_plaintext[11]={0x54, 0x50, 0x2d, 0x4c, 0x69, 0x6e, 0x6b, 0x5f, 0x44, 0x42, 0x30};
byte SSID_cypher[11];
byte SSID_decryptedtext[11];


byte PASS[8]={0x31, 0x33, 0x31, 0x35, 0x31, 0x30, 0x31, 0x30};
byte PASS_cypher[8];
byte PASS_decryptedtext[8];

AES128 aes128;

void encrypt(){
  aes128.encryptBlock(SSID_cypher, SSID_plaintext);//cypher->output block and SSID->input block
  Serial.println();
  Serial.print("After Encryption:");
  
  for(int j=0;j<sizeof(SSID_cypher);j++){
      textAfterEncryption += (char)SSID_cypher[j];
    }
    Serial.print(textAfterEncryption);
    textAfterEncryption = "";


  aes128.encryptBlock(PASS_cypher,PASS);//cypher->output block and SSID->input block
  Serial.println();
  Serial.print("After Encryption:");
  
  for(int j=0;j<sizeof(PASS_cypher);j++){
      textAfterEncryption += (char)PASS_cypher[j];
    }
    Serial.print(textAfterEncryption);
  
}

void decrypt(){
  aes128.decryptBlock(SSID_decryptedtext, SSID_cypher); 
  Serial.println();
  Serial.print("After Decryption:");
  for(int i=0; i<sizeof(SSID_decryptedtext); i++){
    textAfterDecryption += (char)SSID_decryptedtext[i];
   }
   Serial.println(textAfterDecryption);
   textAfterDecryption = "";

  aes128.decryptBlock(PASS_decryptedtext, PASS_cypher);
   
  Serial.println();
  Serial.print("After Decryption:");
  for(int i=0; i<sizeof(PASS_decryptedtext); i++){
    textAfterDecryption += (char)PASS_decryptedtext[i];
   }
   Serial.println(textAfterDecryption);
}

void setup() {
  Serial.begin(9600);
  aes128.setKey(key,16);// Setting Key for AES
  encrypt();
  decrypt();
}

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

}

What I did is I created encrypt() function that encrypts two blocks, then I created the decrypt() function that decrypts the two blocks respectively. Doing so decrypts only the first block successfully while the second block weirdly. The only way that works is to encrypt then decrypt before encrypting anything else like so:

#include <Crypto.h>
#include <AES.h>
#include <string.h>
#include <Arduino.h>

String textAfterEncryption;
String textAfterDecryption;

//key[16] cotain 16 byte key(128 bit) for encryption
byte key[16]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
//SSID[16] contain the text we need to encrypt
byte SSID_plaintext[11]={0x54, 0x50, 0x2d, 0x4c, 0x69, 0x6e, 0x6b, 0x5f, 0x44, 0x42, 0x30};
byte SSID_cypher[11];
byte SSID_decryptedtext[11];


byte PASS[8]={0x31, 0x33, 0x31, 0x35, 0x31, 0x30, 0x31, 0x30};
byte PASS_cypher[8];
byte PASS_decryptedtext[8];

AES128 aes128;

void encrypt(){
  aes128.encryptBlock(SSID_cypher, SSID_plaintext);//cypher->output block and SSID->input block
  Serial.println();
  Serial.print("After Encryption:");
  
  for(int j=0;j<sizeof(SSID_cypher);j++){
      textAfterEncryption += (char)SSID_cypher[j];
    }
    Serial.print(textAfterEncryption);
    textAfterEncryption = "";

  aes128.decryptBlock(SSID_decryptedtext, SSID_cypher); 
  Serial.println();
  Serial.print("After Decryption:");
  for(int i=0; i<sizeof(SSID_decryptedtext); i++){
    textAfterDecryption += (char)SSID_decryptedtext[i];
   }
   Serial.println(textAfterDecryption);
   textAfterDecryption = "";

//----------------------------------------------------------------

//----------------------PASS--------------------------------------
  aes128.encryptBlock(PASS_cypher,PASS);//cypher->output block and SSID->input block
  Serial.println();
  Serial.print("After Encryption:");
  
  for(int j=0;j<sizeof(PASS_cypher);j++){
      textAfterEncryption += (char)PASS_cypher[j];
    }
    Serial.print(textAfterEncryption);
    
   aes128.decryptBlock(PASS_decryptedtext, PASS_cypher);
   
  Serial.println();
  Serial.print("After Decryption:");
  for(int i=0; i<sizeof(PASS_decryptedtext); i++){
    textAfterDecryption += (char)PASS_decryptedtext[i];
   }
   Serial.println(textAfterDecryption);
  
}


void setup() {
  Serial.begin(9600);
  aes128.setKey(key,16);// Setting Key for AES
  encrypt();
}

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

}

I also tried defining two AES128 variables so that I don't use the same one but that also did not work.
Any idea? Thanks!