RSA issues

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!

String stringN = Serial.readString();
unsigned long n = stringN.toInt();
unsigned long e = 65537;

Executable code MUST be in a function. You read NOTHING. You converted that, uselessly, to an int.

You then passed three unsigned longs to a function that expected three signed longs. You stored the signed long return value in an unsigned long variable.

Types matter. Make the function take unsigned longs, or pass it signed longs. Make the function return an unsigned long, or store the result in a signed variable.

And, pass it a decent value based on the string that the python script sends.

Thanks for the quick reply!

You are definitely right about the types, so I changed those. However, I am not quite sure where to then put this piece of code. I do not want to put it in the loop, as it should only be run once. But when I put it in the setup, I cannot use these variables in the loop.

Let it be clear that I am a complete noob when it comes to arduinos, so sorry for that :wink:

But when I put it in the setup, I cannot use these variables in the loop.

You can if you give the variables global scope

Thanks for the help, it is working now!