An RFID reader creates an electro-magnetic field by puting an oscillating at a specific current through a coil. This creates a magnetic field around the coil. The card also has a coil that is able to interact with the field produced by the reader.
It is possible to view the intensity of that field by placing a coil attached to an oscilloscope into the field. Being able to look at the intensity of the field over time allows me to figure out how the field is manipulated in order to transmit information.
Here you can see the voltage through the coil over time, as well as a much longer period of time showing the encoded data.
When a card is presented to the reader, the voltage across the coil drops significantly, that potential most-likely going towards powering the RFID card’s transponder. In adition the voltage changes rapidly over time with a digital appearance. That rapid change in voltage appears to encode the data sent to the reader.
In order to create this effect of changing voltage, we need to assume that the field is created with a constant current and the resistance the card introduces varies. By changing the resistance across the coil in the card, the voltage changes proportionally according to the equation $V=IR$.
For my emulator to be able to successfully fake a card, it needs to be able to change the resistance it places accross the coil. Because the data looks like it’s binary, only on and off, I will choose to change the coil between no resistance (directly connected), and all the resistance (not connected at all).
Card Types
To be able to simulate an RFID card, I need to understand the communication protocols for the different RFID cards I have.
I have a number of different card types available to me such as Mifare Classic & Ultralight cards, NXP DESFire, HID ISOProx II, as well as EM4100 cards. Unfortunately the method I’m going to take to simulate these cards can only send data and cannot understand any data sent by the reader. Only the ISOProx and EM4100 are ‘dumb’ cards, meaning they simply store a number and don’t respond to commands, therefore I’ll be starting by looking into how they work.
In order to investigate the cards’ communication protocols, I’ve connected an oscilloscope to a coil from a broken RFID reader, this will allow me to view the things a RFID Reader can. I’ve placed the coil on top of a working reader and card. And using the oscilloscope I can view the data sent.
HID Prox
Starting out with the ISOProx card, they work with the most common system in North America, HID Prox.
Prox cards have a 26-bit identifier thats interpreted in two parts: facility code, and card number. The cards modulate a frequency shift keyed signal onto the coil. Manually decoding this data would be very difficult with the equipment I have. In addition in order to simulate the card, I may need to create circuitry to recreate the analog signal. In comparison EM4100 cards are simpler, so I’ll be using those.
EM4100
The EM4 series of cards are more common in European and Asian markets, however they are quite cheap and not often seen in commercial use (at least from my observations). Some of the most common RFID locks on eBay use EM4100 cards, like this one:
These cards use simple amplitude shift keying with manchester encoding, that means that the raw bits are directly visible on the oscilloscope screen, and manchester encoding looks at the transition between 1s and 0s to encode the data.
I’ve stitched together a number of screenshots below to show the full data-stream sent from the card.
The data format starts with nine 1s as a header and clock sync period, then followed by 10 4-bit nibbles, each followed by a check-bit. At the end is 4 check-bits calculated across every nibble, followed by a 0 stop bit.
A 1 bit in manchester encoding is represented by a transition from low to high, and a 0 high to low.
Emulator
The emulator was built using a Raspberry Pi pico, a $4 micro-controller, and a coil from a broken RFID Reader. The coil is connected to ground and one of the GPIO pins on the pico. The pico uses programable IO to send the bit-stream as high and low voltage signals, this works because sending a low signal pulls the GPIO to ground, and high signal tries to pull the voltage to 3.3v while disconnecting the pin from ground, effectively changing the coil between low and high impedance states. The reader can then detect the change in impedance as data.