RFID-технология давно стала частью повседневности — мы встречаем её в проездных, пропусках, банковских картах, системах доступа и даже в метках на одежде. Но что на самом деле происходит, когда мы подносим метку к считывателю? Как устроена эта метка внутри? Какие данные она хранит, и как программа может их прочитать или изменить?
Если вы — разработчик и хотите не просто «подключить библиотеку», а понять, как метка устроена на уровне байтов, как работает обмен данными, как выглядит структура памяти и какие команды реально отправляются на устройство, — эта статья для вас.

В этой статье я покажу:
из чего состоит RFID-метка с точки зрения программиста
какие бывают типы и стандарты
как выглядят команды чтения и записи
безопасность RFID-меток: ключи доступа и шифрование
как работать с метками в Python (на примере библиотеки и реального кода)
Без магии. Только практика, низкий уровень и разбор того, что действительно происходит под капотом.
Из чего состоит RFID-метка с точки зрения программиста
Чтобы уверенно работать с RFID на уровне кода, важно понимать, что представляет собой RFID-метка внутри: какие чипы в ней используются, как устроена память, как с ней можно взаимодействовать и программировать её.
Аппаратная часть метки: простая, но умная
RFID-метка — это не просто антенна с чипом. Это радиочастотное устройство, способное принимать команды от считывателя, отвечать на них и выполнять ограниченные операции: чтение, запись, защита памяти и обмен UID.
Типичная пассивная RFID-метка состоит из:
Антенны (медный или алюминиевый контур) — принимает и передаёт сигнал;
Микросхемы (чипа) — управляет протоколом, памятью и шифрованием;
Нет источника питания — она получает энергию по радиоволнам от считывателя (по принципу индукции).

Встроенные модули в чипе
Внутри микросхемы RFID-карты реализовано:
Компонент |
Назначение |
---|---|
EEPROM |
Хранение пользовательских данных |
ROM (ПЗУ) |
Прошитая логика ISO 14443-A и базовых команд |
FSM (finite state machine) |
Обработка протокольной логики (антиколлизия, halt) |
Сравнение ключей (key compare) |
Сравнивает входной ключ с тем, что в памяти |
Access logic |
Проверяет права доступа к каждому блоку |
CRC модуль |
Высчитывает и проверяет CRC |
Какая система счисления используется?
На программном уровне все данные на RFID-метке (например, MIFARE Classic) — это байты. А значит:
Система счисления: двоичная (бинарная)
Представление данных: чаще всего используется шестнадцатеричное (удобно для чтения и анализа байтов)
Примеры:
UID метки:
0xDEADBEEF
Ключ доступа:
0xFF FF FF FF FF FF
Блок данных:
0x41 0x42 0x43 0x44 ...
(соответствует ASCII символамA
,B
,C
,D
…)
Любые 16 байт памяти — это просто массив чисел от 0x00
до 0xFF
(0–255). Программист может интерпретировать эти данные как:
Текст (ASCII, UTF-8)
Числа (uint8, uint32 и т.д.)
Битовые флаги (на уровне отдельных битов)
Хэши или идентификаторы
Какие бывают типы и стандарты
Наиболее распространённые чипы в RFID-метках (в том числе в карточках):
Модель |
Стандарт |
Частота |
Объём памяти |
Примечания |
---|---|---|---|---|
MIFARE Classic 1K |
ISO/IEC 14443A |
13.56 МГц |
1024 байта |
Самый распространённый, дешёвый |
MIFARE Ultralight |
ISO/IEC 14443A |
13.56 МГц |
64 байта |
Очень дешёвый, без криптографии |
NTAG213/215/216 |
NFC Forum Type 2 |
13.56 МГц |
144–888 байт |
Поддержка NFC, в т.ч. для Android/смартфонов |
MIFARE DESFire |
ISO/IEC 14443A |
13.56 МГц |
до 8 КБ |
Поддержка криптографии, сложная структура |
EM4100, TK4100 |
125 кГц |
- |
Read-only |
Используются в дешёвых RFID-брелках |
Как устроена память (на примере MIFARE Classic 1K)
64 блока по 16 байт = 1024 байта
Блоки сгруппированы по секторами по 4 блока
-
Последний блок в секторе — секторный трейлер:
Хранит ключ A, ключ B, и биты доступа (access bits)
Остальные блоки — обычные данные, доступные для чтения/записи после аутентификации
Как программируется RFID-метка
Важно: RFID-метка — это не MCU, в неё нельзя «прошивать код». Она ведёт себя как память с определёнными командами. Программирование = запись данных в её память.
Как выглядят команды чтения и записи
Работа с RFID-меткой (например, MIFARE Classic 1K) сводится к обмену строго определёнными последовательностями байтов. Все команды отправляются считывателем, а метка отвечает в зависимости от состояния и уровня доступа.
Основные команды, которые использует считыватель:
Команда |
Назначение |
Байты |
---|---|---|
|
REQIDL — поиск метки в поле |
1 байт |
|
ANTICOLL — антиколлизия (UID) |
2 байта |
|
AUTH A / B — аутентификация ключом |
12 байт |
|
READ — чтение блока памяти |
2 байта + CRC |
|
WRITE — подготовка к записи |
2 байта + CRC |
|
Передача содержимого блока |
16 байт + CRC |
1) REQIDL — обнаружение метки
[0x26]
Отправляется, чтобы проверить наличие метки в зоне действия. Метка в ответ передаёт два байта (ATQA), если она готова к работе.
2) ANTICOLL — получение UID
[0x93, 0x20]
Начинает процедуру антиколлизии и возвращает UID метки (4 байта) и 1 байт контрольной суммы XOR.
Пример ответа от метки:
[0xDE, 0xAD, 0xBE, 0xEF, 0x11]
Где 0xDEADBEEF
— UID, а 0x11
— XOR всех предыдущих байт.
3) AUTH — аутентификация блока
[0x60, 0x08] + [0xFF]*6 + [UID0, UID1, UID2, UID3]
0x60
— аутентификация с использованием ключа A (0x61
— ключ B)0x08
— номер блока, к которому запрашиваем доступ0xFF ...
— 6 байт ключа (по умолчанию: все 0xFF)UID
— первые 4 байта уникального номера метки
Если всё корректно, метка включает криптографический режим и готова к чтению/записи. Ошибка — команда отклоняется без дальнейшего взаимодействия.
4) READ — чтение блока
[0x30, 0x08]
0x30
— команда чтения0x08
— адрес блока
После команды считыватель добавляет CRC, и если всё корректно, метка отвечает 16 байтами данных.
Пример:
[0x41, 0x42, ..., 0x50] # ASCII ‘A’, ‘B’, ..., ‘P’
5. WRITE — запись данных
Процедура записи состоит из двух этапов:
Шаг 1: запрос записи
[0xA0, 0x08]
0xA0
— команда записи0x08
— адрес блока
Метка должна ответить ACK = 0x0A
— подтверждение готовности принять данные.
Шаг 2: отправка данных
[0x00, 0x01, ..., 0x0F]
16 байт для записи + CRC (счёт автоматически). Если всё хорошо — снова ACK = 0x0A
. Если нет — ошибка записи.
Пример общения по шагам (схематично):
[Модуль] → 0x26 // "Отзовись"
[Чип] ← ATQA (2 байта)
[Модуль] → 0x93 0x20 // "Дай UID"
[Чип] ← UID (4 байта) + BCC
[Модуль] → 0x60 + ключ + UID // "Авторизуйся"
[Чип] ← OK (если ключ верный)
[Модуль] → 0x30 0x08 // "Прочитай блок 8"
[Чип] ← 16 байт данных
Структура памяти MIFARE Classic 1K
Всего: 64 блока по 16 байт
Каждый 4-й блок (например, 3, 7, 11, ...) — служебный, содержит ключи A/B и биты доступа (access bits)
Все остальные блоки — данные (например, блоки 4–6, 8–10 и т.д.)
Безопасность RFID-меток: ключи доступа и шифрование
Работа с RFID-метками — это не только чтение и запись данных, но и обеспечение безопасности. Без должной защиты любой человек с простым считывателем сможет прочитать или изменить содержимое метки. Поэтому важно изменить ключи доступа и настроить биты доступа для ограничения операций.
Как работает безопасность в MIFARE Classic
Каждый сектор (по 4 блока) заканчивается блоком управления (sector trailer), который содержит:
Ключ A (6 байт) — может использоваться для чтения и/или записи
Access Bits (3 байта) — задают разрешения на действия (чтение, запись, смена ключей)
User byte (1 байт) — свободный байт, чаще всего не используется
Ключ B (6 байт) — может использоваться для управления доступом (или быть скрытым)
Важно:
Доступ к каждому сектору возможен только после аутентификации по ключу A или B.
По умолчанию оба ключа равны 0xFFFFFFFFFFFF
, что делает метку уязвимой.
Смена ключей безопасности
Если вы хотите защитить данные, смена ключей — обязательна, особенно для тех секторов, где вы храните важную информацию.
Шаги для смены ключей:
-
Создайте массив из 16 байт:
Первые 6 байт — новый ключ A
Затем 3 байта — access bits
Затем 1 байт — user byte
Последние 6 байт — ключ B
Аутентифицируйтесь к сектору с помощью текущего ключа (обычно
0xFF...
)Запишите массив в блок управления сектора (например, блок 7 — это трейлер сектора 1)
Пример
[
0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB, // Ключ A
0x7F, 0x07, 0x88, // Access Bits
0xFF, // User byte
0xAB, 0xAB, 0xAB, 0xAB, 0xAB, 0xAB // Ключ B
]
А что если повредить блок безопасности?
Если вы случайно:
Запишете некорректные access bits
Сотрёте один байт из трейлера
Перезапишете трейлер случайными данными
...то результат может быть необратим:
Возможные последствия:
Вы потеряете доступ к сектору навсегда (если заданы биты только на чтение без возможности смены ключей)
Нельзя будет прочитать или записать данные, даже зная UID
Метка становится частично или полностью "заблокированной"
Как работать с метками в Python (на примере библиотеки и реального кода)
Для практической работы с RFID-метками мы будем использовать готовую Python-программу из GitHub-репозитория: https://github.com/Elieren/RFID
Это простой, но функциональный интерфейс, позволяющий:
Read card — прочитать все сектора карты
Write UID — изменить UID карты (если она поддерживает перезапись UID)
Write sector — записать данные в конкретный сектор
Read text — считать текст, записанный на карту
Write text — записать произвольный текст на карту
Установка необходимых зависимостей
⚠️ Программа работает только на Raspberry Pi, так как требует доступ к GPIO-пинам и SPI-интерфейсу для работы с считывателем MFRC522.
1) Установим зависимость SPI-Py (необходима для работы с шиной SPI):
git clone https://github.com/lthiery/SPI-Py.git
cd SPI-Py/
git checkout 8cce26b9ee6e69eb041e9d5665944b88688fca68
sudo python3 setup.py install
2) Включим SPI на Raspberry Pi:
sudo nano /boot/config.txt
Добавьте в конец файла строку:
dtparam=spi=on
Сохраняем и перезагружаемся:
reboot
3) Устанавливаем библиотеку MFRC522 для Python:
pip3 install mfrc522
Подключение модуля RFID-RC522
Вот распиновка подключения к Raspberry Pi:
Название |
Пин № |
GPIO |
---|---|---|
SDA |
24 |
GPIO8 |
SCK |
23 |
GPIO11 |
MOSI |
19 |
GPIO10 |
MISO |
21 |
GPIO9 |
IRQ |
— |
— |
GND |
Любой |
Ground |
RST |
22 |
GPIO25 |
3.3V |
1 или 17 |
3.3V |
Убедитесь, что всё подключено корректно и модуль получает питание.
Запуск программы
Теперь всё готово. Просто запустите основной скрипт:
sudo python3 RFID.py
На экране появится ASCII-интерфейс:
██████╗ ███████╗██╗██████╗ ███████╗ ██████╗██████╗ ██╗██████╗ ████████╗
██╔══██╗██╔════╝██║██╔══██╗ ██╔════╝██╔════╝██╔══██╗██║██╔══██╗╚══██╔══╝
██████╔╝█████╗ ██║██║ ██║ ███████╗██║ ██████╔╝██║██████╔╝ ██║
██╔══██╗██╔══╝ ██║██║ ██║ ╚════██║██║ ██╔══██╗██║██╔═══╝ ██║
██║ ██║██║ ██║██████╔╝███████╗███████║╚██████╗██║ ██║██║██║ ██║
╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚══════╝╚══════╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═╝
[1] Read card
[2] Write UID
[3] Write sector
[4] Clear card
[5] Read text
[6] Write text
:
Что можно сделать
Выбираете нужную опцию и следуете подсказкам. Возможности:
Считать UID карты
Заменить UID (если карта позволяет)
Перезаписать конкретный сектор (16 байт)
Очистить все сектора (кроме ключей и трейлеров)
Прочитать текстовые данные
Записать строку текста на карту
Все операции работают через низкоуровневый доступ к командам MFRC522, с использованием байтов и аутентификации по ключам.
Вывод
Теперь мы понимаем, как работает RFID-карта глазами программиста.
Мы разобрали:
Как внутри чипа обрабатываются байтовые команды на самом низком уровне
Как устроена память RFID-чипа: блоки, сектора, ключи, access bits
Как выполнять операции чтения, записи и смены ключей через Python
Как чип проверяет команды, защищает данные и формирует ответ
Важно помнить: чип не "думает", он просто исполняет прошитую логику и реагирует на команды по строго заданному протоколу. Это делает RFID одновременно простым и надёжным инструментом хранения и передачи данных на короткие расстояния.
Спасибо за чтение.
Надеюсь, статья помогла вам разобраться в RFID не только на уровне "поднес — сработало", но и на уровне байтов, протоколов и внутренней логики работы чипа.
photobum
Подскажите, пожалуйста, библиотеку для работы с модулем MFRC522 на ESP32