Professional Documents
Culture Documents
MCU Based RSA Encrypted Card Entrance System Via RFID Cards and RF Communication Project
MCU Based RSA Encrypted Card Entrance System Via RFID Cards and RF Communication Project
MCU Based RSA Encrypted Card Entrance System via RFID Cards and RF
Communication Project Report
Mustafa Alper BALIM
Bursa Technical University
Background
RSA is a useful cryptology method for using projects that use 8 and 16 bit MCUs. In this
project; there are two MCU based control unit. First unit reads the RFID card, and second
unit allows or rejects entries by controlling the door.
Communication will be made by RF communication modules as encrypted via RSA. First unit
will send RFID card ID by encrypting it. Second unit will decrypt received data and will decide
to allow or reject entrance. Then second unit will encrypt the answer of entrance request to
first unit. First unit will decrypt the answer and will allow/reject the user.
Hardware
The system consist of two MCUs , an MIFARE RFID Card Reader and two RF
communication modules. Each RF modules has two part that recieve and transmit data.
Two Arduino Nano based Atmega328 is used as MCUs and proggrammed via Proccesinglike Arduino language.
MCUs and RF Modules communicates with each other via software serail communication.
RFID reader communicates via SPI(Serial Peripheral Interface).
Software
Encryption Block:
Encryption block computes the ciphertext c for plaintext p using the public key e for
every character.
= ( )
encrypt(char) function returns two character because ciphertext c that computed is too
large for standart ANSII char variable and values that will be sent by RF module must be
char variable type. First 8 bit of c is kept in cipherText[ctr] and last 8 bit is kept in
cipherText[ctr+1]. cipherText[] array is doubled.
If p and q is choosen too large, c will be larger than 2 character (bytes) and, cipherText
has to be divided into 3 or more. Because of we have limited memory and limited computing
capacity, p and q has to be chosen smaller then 100.
Decryption Block:
Decryption block computes the plaintext p for ciphertext cusing the private key d for
every character.
= ( )
decrypt(char) function gets two character that computed by encrypt() function and returns
one character that belongs to plaintext.
Before the computing char array will be reassembled to long variable type by combining
two characters cipherText[ctr] and cipherText[ctr+1]. After computing, computed M is
smaller then c (one byte). But it is still stored as two (or more) bytes. ). M & 0xFF operator
masks first 8 bit of M. And thats equals plainText[i], ith character of plaintext.
ctr = i * sizeof(int);
{
//Reassemble the divided cipher characters to temp value.
temp = (((unsigned char)cipherText[ctr + 1] << 8) | (unsigned char)cipherText[ctr]);
for(int j = 0; j < d; j++)
{
M = (M * temp) % n;
}
Every step of application is printed to Arduino IDE Serial Monitor for observing with serial
communication by USB ports.
Source Codes
Source Code of Central MCU:
#include <VirtualWire.h>
char cipher_msg[200];
char plain[25];
//--------------------------------------int p;
int q;
int n;
int t;
int w;
int e;
int d;
int flag;
//--------------------------------------char recieved_data[200];
boolean stringComplete = false;
String stringRecieved;
void setup()
{
Serial.begin(9600);
vw_set_rx_pin(A5);
vw_set_tx_pin(A4);
vw_rx_start();
p=37;
q=41;
w=3;
n=p*q;
t=(p-1)*(q-1);
find_e();
//Print parameters.
Serial.print("P=");Serial.println(p);
Serial.print("Q=");Serial.println(q);
Serial.print("N=");Serial.println(n);
Serial.print("T=");Serial.println(t);
Serial.print("E=");Serial.println(e);
Serial.print("D=");Serial.println(d);
}
void loop()
{
uint8_t buf[320];
uint8_t buflen = 320;
vw_setup(2000);
vw_wait_rx(); //Wait if data is not recieved
RF_Read();
if(stringComplete) //If data not recieved
{
Serial.print("ifreli ID Alnd: ");
Serial.println(stringRecieved);
Serial.print("Kart ID zlyor: ");
decrypt(plain, recieved_data);
String plaintxt="";
//CharArray to String Conversation
for(int i = 0; i <= 25; i++) {plaintxt+=plain[i];}
Serial.println(plaintxt);
String Name = "";
//Users
if(plaintxt=="227435119")
else if(plaintxt=="1821504759")
else
if(plaintxt!="not")
else if(plaintxt=="not")
Name="yAlper ";
Name="yMisafir ";
Name="not";
Serial.println("ID Eleti");
Serial.println("ID Elemedi");
char charName[20];
Name.toCharArray(charName,20);
encrypt(charName, cipher_msg);
Serial.print("Cevap ifreleniyor: ");
for(int i = 0; i < buflen; i++) {Serial.print(cipher_msg[i]);}
Serial.println();
const char* mesaj = (const char*) cipher_msg;
vw_setup(2000);
vw_send((uint8_t *)mesaj, 320);
}
Serial.println("///////////////////////////////////////////////////////////
");
Serial.println("");
}
// Read data from RF recieve buffer.
void RF_Read()
{
stringRecieved = "";
recieved_data[320] = {};
char inChar;
uint8_t buf[320];
uint8_t buflen = 320;
if (vw_get_message(buf, &buflen))
{
for (int i = 0; i < buflen; i++)
{
inChar = buf[i];
recieved_data[i]=buf[i];
stringRecieved+=inChar;
}
stringComplete=true;
}
}
void find_e()
{
int k=0;
for(int i=2;i<t;i++)
{
if(t%i==0) continue;
flag=is_prime(i);
if(flag==1&&i!=p&&i!=q)
{
e=i;
flag=find_d(e);
if(flag>0)
{
d=flag;
if(k==w)break;
k++;
}}}}
//finds d for e
int find_d(int x)
{
int k=1;
while(1)
{
k=k+t;
if(k%x==0)
//k=( k+t) mod(t)
return(k/x); //If appropriated is found return d
}
}
//Returns "1" if "pr" is a prime number.
int is_prime(int pr)
{
int j;
j=sqrt(pr);
for(int i=2;i<=j;i++)
{
if(pr%i==0)
return 0;
}
return 1;
}
void encrypt(char *plainText, char *cipherText)
{
long m = 1;
int ctr = 0;
for(int i = 0; i < 20; i++)
//For every character
{
for(int j = 0; j<e ; j++) //m = plainText()^e (mod n)
{
m = (m * plainText[i]) % n;
}
9
10
//Print parameters.
Serial.print("P=");Serial.println(p);
Serial.print("Q=");Serial.println(q);
Serial.print("N=");Serial.println(n);
Serial.print("T=");Serial.println(t);
Serial.print("E=");Serial.println(e);
Serial.print("D=");Serial.println(d);
}
void loop()
{
uint8_t buf[320];
uint8_t buflen = 320;
//Wait for new card
if ( ! mfrc522.PICC_IsNewCardPresent()) return;
if ( ! mfrc522.PICC_ReadCardSerial()) return;
Serial.print("Kart ID Okunuyor: ");
ID_Read();
mfrc522.PICC_HaltA();
Serial.println(stringID);
Serial.print("Kart ID ifreleniyor: ");
encrypt( cardID, cipher_msg);
for(int i = 0; i < buflen; i++)
Serial.print(cipher_msg[i]);
Serial.println();
Serial.println("ifreli ID Gnderiliyor...");
const char* mesaj = (const char*) cipher_msg;
vw_setup(2000);
vw_send((uint8_t *)mesaj, buflen);
Serial.println("Giri zni Bekleniyor");
delay(4500); //Wait for Central MCU's Answer
RF_Read(); // Read data from RF recieve buffer.
Serial.println("Cevap Alnd");
decrypt(plain, gelen_veri);
String plaintxt="";
for(int i = 0; i <= plaintxt.length()+1; i++)
plaintxt+=plain[i];
if(plaintxt=="not")
Serial.println("Giri zni Verilmedi");
else if(plain[0]=='y')
{
Serial.print("Giri zni Verildi => ");
Serial.print("Kullanc:");
for(int i=1;i<25;i++) Serial.print(plain[i]);
Serial.println("");
digitalWrite(door_open, HIGH);
digitalWrite(door_closed, LOW);
}
plain[0]='x';
Serial.println("///////////////////////////////////////////////////////////
");
Serial.println("");
delay(3000);
digitalWrite(door_open, LOW);
//Open Door
digitalWrite(door_closed, HIGH); // Close Door
}
//Read Card ID and convert to char array and string
void ID_Read()
{
stringID="";
for (int i = 0; i < 4; i++)
{
readCard[i] = mfrc522.uid.uidByte[i];
stringID+=readCard[i];
}
sizeID=stringID.length()+1;
stringID.toCharArray(cardID, sizeID ) ;
}
//// Read data from RF recieve buffer and convert to string and char array.
void RF_Read()
{
uint8_t buf[320];
uint8_t buflen = 320;
stringGelen = "";
gelen_veri[320] = {};
char inChar;
if (vw_get_message(buf, &buflen))
{
for (int i = 0; i < buflen; i++)
{
inChar = buf[i];
gelen_veri[i]=buf[i];
stringGelen+=inChar;
}
stringComplete=true;
}}
void find_e()
{
int k=0;
for(int i=2;i<t;i++)
{
if(t%i==0) continue;
flag=is_prime(i);
if(flag==1&&i!=p&&i!=q)
{
e=i;
flag=find_d(e);
if(flag>0)
{
d=flag;
if(k==w)break;
k++;
}}}}
int find_d(int x)
{
int k=1;
while(1)
{
k=k+t;
if(k%x==0)
return(k/x);
}}
int is_prime(int pr)
{
int j;
j=sqrt(pr);
for(int i=2;i<=j;i++)
{
if(pr%i==0)
return 0;
}
return 1;
}
void encrypt(char *plainText, char *cipherText)
{
long m = 1;
int ctr = 0;
for(int i = 0; i <sizeID ; i++)
{
for(int j = 0; j<e ; j++)
{
m = (m * plainText[i]) % n;
}
ctr = i * sizeof(int);
cipherText[ctr]
= (char) (m & 0x00ff);
cipherText[ctr + 1] = (char) ((m & 0xff00) >> 8);
m = 1;
}}
void decrypt(char *plainText, char *cipherText)
{
long M = 1;
int temp = 0;
int ctr = 0;
//re-assemble char array to array of int
for(int i = 0; i < sizeID; i++) {
ctr = i * sizeof(int);
temp = (((unsigned char)cipherText[ctr + 1] << 8) | (unsigned
char)cipherText[ctr]);
for(int j = 0; j < d; j++) {
M = (M * temp) % n;
}
plainText[i] = (unsigned char)(M & 0xFF);
M = 1;
}}