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) сводится к обмену строго определёнными последовательностями байтов. Все команды отправляются считывателем, а метка отвечает в зависимости от состояния и уровня доступа.

Основные команды, которые использует считыватель:

Команда

Назначение

Байты

0x26

REQIDL — поиск метки в поле

1 байт

0x93 0x20

ANTICOLL — антиколлизия (UID)

2 байта

0x60 / 0x61

AUTH A / B — аутентификация ключом

12 байт

0x30 XX

READ — чтение блока памяти XX

2 байта + CRC

0xA0 XX

WRITE — подготовка к записи

2 байта + CRC

[16 байт данных]

Передача содержимого блока

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, что делает метку уязвимой.

Смена ключей безопасности

Если вы хотите защитить данные, смена ключей — обязательна, особенно для тех секторов, где вы храните важную информацию.

Шаги для смены ключей:

  1. Создайте массив из 16 байт:

    • Первые 6 байт — новый ключ A

    • Затем 3 байта — access bits

    • Затем 1 байт — user byte

    • Последние 6 байт — ключ B

  2. Аутентифицируйтесь к сектору с помощью текущего ключа (обычно 0xFF...)

  3. Запишите массив в блок управления сектора (например, блок 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 не только на уровне "поднес — сработало", но и на уровне байтов, протоколов и внутренней логики работы чипа.

Комментарии (1)


  1. photobum
    23.06.2025 13:20

    Подскажите, пожалуйста, библиотеку для работы с модулем MFRC522 на ESP32