{"id":45444165,"url":"https://github.com/abobija/nfcity","last_synced_at":"2026-02-22T03:52:29.287Z","repository":{"id":258847025,"uuid":"862816939","full_name":"abobija/nfcity","owner":"abobija","description":"Deep dive into NFC cards","archived":false,"fork":false,"pushed_at":"2025-08-27T05:51:04.000Z","size":1735,"stargazers_count":11,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-07T01:26:14.899Z","etag":null,"topics":["card","esp-idf","memory","mfrc522","nfc","read-write","web"],"latest_commit_sha":null,"homepage":"https://abobija.github.io/nfcity/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abobija.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"abobija"}},"created_at":"2024-09-25T08:36:15.000Z","updated_at":"2025-08-27T05:51:07.000Z","dependencies_parsed_at":"2024-10-22T01:47:17.262Z","dependency_job_id":null,"html_url":"https://github.com/abobija/nfcity","commit_stats":null,"previous_names":["abobija/nfcity"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/abobija/nfcity","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abobija%2Fnfcity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abobija%2Fnfcity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abobija%2Fnfcity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abobija%2Fnfcity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abobija","download_url":"https://codeload.github.com/abobija/nfcity/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abobija%2Fnfcity/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29704420,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-22T03:17:42.375Z","status":"ssl_error","status_checked_at":"2026-02-22T03:17:31.622Z","response_time":110,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["card","esp-idf","memory","mfrc522","nfc","read-write","web"],"created_at":"2026-02-22T03:52:29.225Z","updated_at":"2026-02-22T03:52:29.281Z","avatar_url":"https://github.com/abobija.png","language":"TypeScript","funding_links":["https://github.com/sponsors/abobija"],"categories":[],"sub_categories":[],"readme":"# NFCity\n\nProject that provides a simple way to inspect and modify memory of NFC/RFID cards.\n\n[![web-app-dashboard](docs/web-app-dashboard.png)](https://youtu.be/X7W1hfjEc5A)\n\nThrough an in-browser web application, you can unlock and modify the card's memory blocks.\n\nProject page:\nhttps://abobija.com/projects/nfcity-esp32-nfc-card-tool\n\n## 1. Motivation\n\nWhile developing a [library](https://github.com/abobija/esp-idf-rc522) for interacting with NFC cards using the [MFRC522](https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf) reader, I gained significant knowledge about card memory structure and interaction. This knowledge came from reading datasheets and through trial and error. These resources are often technical and difficult for beginners, but they contain valuable information on how NFC cards work.\n\nAlthough libraries for NFC card interaction are helpful, they usually hide the card's complexity, offering only a high-level API for reading and writing data. This project aims to provide a simple way to directly interact with NFC card memory, offering a detailed view of how the memory is structured, how to write data, and how to configure access conditions and sector keys.\n\n## 2. Architecture\n\nThe project consists of three main components:\n\n- Device (ESP32 with an attached RC522 reader)\n- Web Application (Single Page Application)\n- Messaging Bus (MQTT)\n\nCommunication between the device and the web application is handled asynchronously via the MQTT bus. The device publishes messages to the bus, while the web application subscribes to these messages. To read or write data, the web application sends a request to the device, which processes the request and responds.\n\n```mermaid\nsequenceDiagram\n    participant D as Device\n    participant M as MQTT Broker\n    participant W as Web Application\n\n    D-\u003e\u003eM: Hello, Im booted!\n    D-\u003e\u003eM: New NFC card detected\n    M-\u003e\u003eW: NFC card info (UID, SAQ, ...)\n    W-\u003e\u003eM: Unlock and read sector 15\n    M-\u003e\u003eD: App wants to read sector 15\n    D-\u003e\u003eM: Blocks from sector 15\n    M-\u003e\u003eW: Here is the content of sector 15\n    W-\u003e\u003eM: Write data to block 0x3F\n    M-\u003e\u003eD: App wants to write to block 0x3F\n    D-\u003e\u003eM: Block 0x3F has been updated\n    M-\u003e\u003eW: Updated content of block 0x3F\n```\n\nThe diagram above shows a typical workflow for message exchange between the web application and the device.\n\n### 2.1. Web Application\n\nThe web application is a Single Page Application (SPA) built with Vue. It communicates with the device solely through the MQTT bus using WebSockets. The goal is to provide an easy-to-use interface for inspecting and modifying NFC cards.\n\nIf you've manually modified Mifare blocks before, you're aware of the complexity in properly building the data for the Sector Trailer block to avoid corrupting the card. This application simplifies that process by offering a user-friendly interface for modifying access bits, keys, and data blocks.\n\nThe application has a retro-hacker look and feel, with a synthwave color palette and a monospace font. Currently, it’s not fully responsive and is best viewed on desktop.\n\n### 2.2. Device\n\nThe device is an ESP32 microcontroller with an attached [MFRC522](https://www.nxp.com/docs/en/data-sheet/MFRC522.pdf) reader. Once powered on, it connects to the local network and the MQTT bus, waiting for incoming messages from the web application. Upon receiving a message, the device processes it and sends a response back. Most messages from the web app involve operations on the NFC card, such as reading or writing data to memory sectors.\n\nThe firmware is written in C using the [ESP-IDF](https://github.com/espressif/esp-idf) framework. It leverages ESP-IDF's MQTT library for broker communication and the MFRC522 [library](https://github.com/abobija/esp-idf-rc522) for NFC card interaction.\n\n## 3. Installation\n\n### 3.1. Web Application\n\n\u003e [!TIP]\n\u003e If you want to skip building the application yourself, you can use the [hosted version](https://abobija.github.io/nfcity)\n\nThe web application is located in the [`web`](web/) directory. To build it, you'll need Node.js and npm installed. To run the application in development mode with hot-reloading, use the following commands:\n\n```bash\ncd web\nnpm install\nnpm run dev\n```\n\nOnce the commands run successfully, the terminal will display the local address where the application is hosted. Open that address in your browser.\n\n### 3.2. Device\n\n### 3.2.1. Hardware\n\nThe device consists of an ESP32 microcontroller and an MFRC522 reader. The wiring is as follows:\n\n| ESP32 | MFRC522 |\n|-------|---------|\n| 21    | MISO    |\n| 23    | MOSI    |\n| 19    | SCLK    |\n| 22    | SDA     |\n| 18    | RST     |\n\n### 3.2.2. Firmware\n\nThe device firmware is in the [`firmware`](firmware/) directory. To build and flash the firmware to the ESP32, you must have ESP-IDF installed. Follow the instructions in the [official documentation](https://docs.espressif.com/projects/esp-idf/en/v5.3.1/esp32/get-started/index.html). \n\nOnce ESP-IDF is installed, navigate to the `firmware` directory. Execute next command to configure the project:\n\n```bash\nidf.py menuconfig\n```\n\nIn the configuration menu, set the next options:\n\n| Option        | Path                                                  |\n|---------------|-------------------------------------------------------|\n| WiFi SSID     | `Example Connection Configuration` -\u003e `WiFi SSID`     |\n| WiFi Password | `Example Connection Configuration` -\u003e `WiFi Password` |\n| MQTT Broker   | `NFCity` -\u003e `MQTT Broker`                             |\n\n\nSave and exit the configuration menu. Then, build and flash the firmware:\n\n```bash\nidf.py build flash monitor\n```\n\nIf the correct WiFi credentials are set, the terminal should show that the device has connected to the network and MQTT broker.\n\n\u003e [!IMPORTANT]\n\u003e In the terminal, a randomly generated root topic will appear. The device uses this topic for publishing messages to the MQTT broker. Use this root topic in the web application to subscribe to messages from the device. Root topics are unique to each device to avoid message collisions on public brokers. It's saved in the device's flash memory and will persist across reboots.\n\n## 4. Usage\n\nWhen you open the web application, the first step is to copy the root topic from the Device's terminal and paste it into the client configuration form. \n\n![root-topic-pairing](docs/root-topic-pairing.png)\n\nSave configuration and click the connect button to connect to the MQTT broker. The configuration is saved in the browser's local storage, so you don’t need to re-enter it every time.\n\nAfter connecting to the broker, place an NFC card on the reader. Once detected, the card info will appear in the app, and you can start reading and writing data to the card.\n\n## 5. Support\n\nThe project currently supports cards that are compatible with the underlying firmware [library](https://github.com/abobija/esp-idf-rc522) used for communication with the MFRC522 reader. This includes cards from the Mifare Classic family, such as Mifare 1k, 4k, and Mini.\n\n## 6. Author\n\nGitHub: [abobija](https://github.com/abobija)\u003cbr /\u003e\nHomepage: [abobija.com](https://abobija.com)\n\n## 7. License\n\nThis project is licensed under Apache License 2.0. See the [LICENSE](LICENSE.txt) file for more details.\n\n## 8. Issues and Contributions\n\nThere are many features that can be added. If you have suggestions or want to contribute, feel free to open an issue or a pull request. All feedback and improvements are welcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabobija%2Fnfcity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabobija%2Fnfcity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabobija%2Fnfcity/lists"}