Dear forum people,
for a school project I am working on building an RFID system, using an arduino, python, and a database. It is obligatory to add an RSA encryption to this system. The RFID system on itself works, but when I try to add the RSA to it, something goes horribly wrong. Here is my code:
Arduino part:
/*
MFRC522 - Library to use ARDUINO RFID MODULE KIT 13.56 MHZ WITH TAGS SPI W AND R BY COOQROBOT.
The library file MFRC522.h has a wealth of useful info. Please read it.
The functions are documented in MFRC522.cpp.
Based on code Dr.Leong ( WWW.B2CQSHOP.COM )
Created by Miguel Balboa (circuitito.com), Jan, 2012.
Rewritten by Søren Thing Andersen (access.thing.dk), fall of 2013 (Translation to English, refactored, comments, anti collision, cascade levels.)
Released into the public domain.
Sample program showing how to read data from a PICC using a MFRC522 reader on the Arduino SPI interface.
----------------------------------------------------------------------------- empty_skull
Aggiunti pin per arduino Mega
add pin configuration for arduino mega
http://mac86project.altervista.org/
----------------------------------------------------------------------------- Nicola Coppola
Pin layout should be as follows:
Signal Pin Pin Pin
Arduino Uno Arduino Mega MFRC522 board
------------------------------------------------------------
Reset 9 5 RST
SPI SS 10 53 SDA
SPI MOSI 11 51 MOSI
SPI MISO 12 50 MISO
SPI SCK 13 52 SCK
The reader can be found on eBay for around 5 dollars. Search for "mf-rc522" on ebay.com.
*/
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
int buzzpin = 7;
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
pinMode(buzzpin, OUTPUT);
// confirm connection
Serial.write('0');
}
// source: http://stackoverflow.com/questions/32839396/how-to-get-the-uid-of-rfid-in-arduino
unsigned long getUID() {
if ( ! mfrc522.PICC_ReadCardSerial()) {
return -1;
}
unsigned long UID;
UID = mfrc522.uid.uidByte[0] << 24;
UID += mfrc522.uid.uidByte[1] << 16;
UID += mfrc522.uid.uidByte[2] << 8;
UID += mfrc522.uid.uidByte[3];
mfrc522.PICC_HaltA(); //StopReading
return UID;
}
// end of source
//function used for encrypting a message (integer!)
//Input: message, N, e. Where n and e are from the given public key(N,e)
//cipher = (message ^ e) mod N
//It is based on the pseudo code from the lecture slides.
//It does however not work with bits as input.
using namespace std;
long Encrypt(long message, long nn, long ee) {
long remainder;
long r = 1;
long b = message;
while (ee != 0) {
//This is used to not have to use bits.
//For example: 7 is 1110 in binary. remainder = (e=7)%2 = 1, then e becomes 3.
//This triggers the if statement. This cycle repesents the left most 1 in 1110).
//A new cycle happens: remainder = (e=3)%2=1, then e becomes 1.
//This also triggers the if statement. This represents the second left most 1 in 1110.
//etc
remainder = ee % 2;
ee = ee / 2;
if (remainder == 1) {
r = (r * b) % nn;
b = (b * b) % nn;
}
long cipher = r;
return cipher;
}
}
unsigned int check;
// recieve RSA keys
String stringN = Serial.readString();
unsigned long n = stringN.toInt();
unsigned long e = 65537;
void loop() {
// Send the UID
if (mfrc522.PICC_IsNewCardPresent()) {
unsigned long UID = getUID();
if (UID != -1) {
unsigned long encryptUID = Encrypt(UID, n, e);
Serial.println(encryptUID);
delay(50);
// Play the right tone
check = Serial.read();
if (check == 2) {
tone(buzzpin, 311, 125);
delay(125);
tone(buzzpin, 349, 125);
delay(125);
tone(buzzpin, 392, 500);
check = 0;
Serial.write("0");
} else if (check == 1) {
tone(buzzpin, 262, 750);
delay(900);
tone(buzzpin, 262, 750);
delay(900);
tone(buzzpin, 262, 750);
check = 0;
Serial.write("0");
} else {
check = 0;
Serial.write("0");
}
// Getting the public key
// unsigned long n = Serial.readString().toInt();
}
}
}
And here is the python part:
import serial
import struct
import rsa
from database import *
# open port
ser = serial.Serial('COM4', 9600)
# check for a connection
connected = False
while not connected:
serin = ser.read()
connected = True
print(connected)
if connected:
# send RSA keys
(publickey, privatekey) = rsa.newkeys(32)
print(publickey.n)
ser.write(bytes(str(publickey.n), 'utf-8'))
while connected:
# read UID
byteUID = ser.readline()
enterUID = byteUID.decode("utf-8")
encryptUID = enterUID.rstrip()
UID = rsa.decrypt(encryptUID, privatekey)
# deny or grant access
if whitelist(UID):
print("Access granted")
ser.write(struct.pack('>B', 2))
#check in user
check(UID)
serin = ser.read()
else:
print("Acces denied")
ser.write(struct.pack('>B', 1))
serin = ser.read()
# send new RSA keys
#(publickey, privatekey) = rsa.newkeys(64)
# print(publickey.n)
# ser.write(bytes(str(publickey.n), 'utf-8'))
The problem seems to be that the Arduino does not send the '0' in the setup to confirm the connection, but instead gets stuck somewhere in the setup. Which is weird, since it does work when I remove all the RSA parts. The fact that the 'L' LED on my Arduino Uno stays on, seems to confirm this hypothesis.
Any ideas as to what might be the problem? Thanks in advance!