Thursday, February 19, 2015

Security card reader

This post describes a quick-and-dirty proof-of-concept that I recently did using a Wiegand card reader and a Raspberry Pi.

One of our executives at work saw a kiosk that read people’s ID cards as they walked up to it and displayed some personalized content. He asked if we had anything that could do that. I thought this could be an interesting weekends-and-nights project that would result in a basic, demoable proof-of-concept system. There was enough new-to-me technology involved that I thought it would be a worthwhile learning exercise.

When I start a new project I put together a hypothetical architecture and design based on what I think is necessary to achieve the objectives of the project. I list all of the pieces of the problem space that I don’t understand along with pieces that I think I can use. The pieces I don’t understand, typically expands as I get into research mode - I found I didn't know much about card reader technology before I started... 

I hypothesized that I could use a Raspberry Pi to decode data from the scanner and implement a web page that displays the data. I’d use a mySQL database to store the card data and an Apache web server to display the output.


I’m generally a cheapskate, so I look for ways to use whatever I have on hand whenever possible. In this case, the Raspberry Pi seemed to be a good fit – I’d used it for a couple of other projects and knew that it was quite a powerful little computer. I know enough Linux to be dangerous and thought it would be easier developing software in this environment than figuring out how to interface the scanner to a Windows PC (and the only Windows PC I have at home is an old XP laptop...)

The card’s I selected to test with were HID 125KHz proximity cards, selected because of their ubiquity in security applications - and because I had one. These cards have a little processor and antenna embedded in them that, when placed near the electromagnetic field of a scanner, power up and disrupt the field slightly, transmitting 26 bits of information. There are a couple of parity bits, an 8 bit “facility code” and a 16 bit “cardID”. The specs and the interface protocol were all available on-line.

There were a number of cheap, used scanners on e-bay so I ordered one to test with for about $40. I figured that if I couldn't make it work, this was a cheap way to fail. A more capable, longer range scanner, the MaxiProx HID reader, costs about 10X the cheap unit I bought. If the PoC worked, I could swap in the more capable scanner later for longer range scans.

I found that someone (Ben Kent) had already done some development of Wiegand software in C that I could hack for the Raspberry Pi application. The Wiegand interface uses two data lines and a ground wire and works over long distances. Typically the scanners are at building points of entry and the wires have to be routed through walls, ceilings and floors to get to wherever their authorization system is located. The Wiegand protocol works well for these long cable runs. The software gets an interrupt when either of the data lines signals and then turns these events into bits that it accumulates until it has 26 of them.

Just to make sure that the scanner was working, I hooked up the data lines to a dual trace memory scope and captured a card scan. I was able to visually convert the oscilloscope traces to the 1s and 0s of the number embedded on my ID card.


Using a couple of resistors and zener diodes I built a quick and dirty converter to scale the 0-5V output of the scanner to a 0-3.3V signal that the RPi could deal with.  I loaded a current version of Linux onto the RPi and downloaded, installed and updated the software I thought I’d need: Apache, php, mySQL and a gcc compiler and verified that each of the components worked. This is all pretty standard for the Raspberry Pi, so it was easy to get running.

Since I hadn’t used mySQL before and had only written a couple of small php apps, I wrote some test programs to demonstrate that I could read and write to the database from C and php applications. This took most of the “development” time – totaling maybe 6-8 hours – mostly googling for C and php subroutines that could read and write mySQL data and then playing with them until they worked. For hacking together these simple programs, the RPi worked fine.  This resulted in a couple dozen lines of php code and maybe 150 lines of C. 

A quick test of the software showed that it was indeed capturing the 1’s and 0’s from the Wiegand interface. And a little more development got me an app that stored the scanned card info to a database. A php app running on the RPi’s Apache server queried the database that I had created to translate card number into a name. It then opened a couple of search pages using the name. I had all the software auto-load at startup so that I could run the RPi "headless" (without a monitor, keyboard or mouse attached.)

This project took maybe 10-12 hours of research, software and hardware hacking spread over a couple of weeks with less than $100 in hardware budget (much of it stuff I already had.) I learned something about Apache, php, mySQL coding in C, Wiegand encoded cards and 125KHz scanners. Well worth the time!

My point in documenting this journey and others like it is not to provide a step-by-step guide so that you can reproduce what I did – this stuff is just not that complicated and you’ll probably find a better way to do it anyway… 

I just want to demonstrate that it's really about breaking the problem down into known and unknown chunks, learning the unknown parts, playing with each individual piece of the puzzle to understand it, and then hacking these pieces together until it works. The Linux platform is great for integrating different technologies, because most of the necessary software is open source and free. And the Raspberry Pi is a great Linux platform because of all the support it enjoys and the ease with which it can connect to, well, anything. Also, if you're a Mac user, most of the same tools are available on the Mac - it's based on UNIX so it's easy to move back and forth between it and Linux.

If you can think it, you can do it!



No comments:

Post a Comment