Копирование RFID-карт с помощью ODRFID-M/N/E
Как перенести UID и данные RFID-карты с помощью ODRFID-M/N/E: через ODRFIDKit, вручную AT-командами и из программы на Python.
Слово «скопировать» применительно к RFID-карте может означать совершенно разные операции. Иногда системе достаточно того же UID. В другом проекте важны данные в секторах MIFARE Classic или пользовательских страницах NTAG. А защищённая карта может проверять ключи, счётчики и криптографические ответы, которые не копируются как обычный набор байтов.
Настольные считыватели ODRFID-M/N/E позволяют разобрать задачу по частям: считать исходную метку, определить её тип, перенести доступные данные и проверить результат. Для интерактивной работы подходит бесплатная программа ODRFIDKit, а для автоматизации — текстовые AT-команды через виртуальный COM-порт. Это практичнее и безопаснее, чем пытаться записать «полный дамп» вслепую.
Используйте эти функции только для собственных карт, тестовых стендов и систем, на обслуживание которых у вас есть разрешение.
Что именно можно скопировать
| Что переносим | Откуда | Куда | Что потребуется |
|---|---|---|---|
| 4-байтный UID | MIFARE Classic 13,56 МГц | Специальная Classic-совместимая карта с перезаписываемой UID-областью | ODRFID-M или ODRFID-N |
| UID EM4100 | EM-Marine 125 кГц | T5557/T5567/T5577 или совместимая заготовка в режиме эмуляции EM4100 | ODRFID-M или ODRFID-E |
| Блоки данных | MIFARE Classic и поддерживаемые режимы MIFARE Plus | Карта совместимого семейства и размера | Ключ чтения исходной карты и право записи в целевую |
| Пользовательские страницы | MIFARE Ultralight EV1, NTAG 213/215/216 | Совместимая метка с достаточным объёмом памяти | PWD/PACK, если страницы защищены |
UID и память — не одно и то же. Копирование только UID не переносит содержимое секторов. Копирование пользовательских блоков на обычную карту, наоборот, не меняет её заводской UID. Полная функциональная копия возможна только тогда, когда целевая микросхема поддерживает все нужные операции, а используемая система не проверяет дополнительные криптографические признаки.
Что подготовить
- настольный ODRFID-M, ODRFID-N или ODRFID-E под нужную частоту;
- ODRFIDKit для Windows, Linux или macOS, ODRFIDKit Web в совместимом браузере либо терминал/собственную программу для работы через USB CDC;
- исходную карту и совместимую перезаписываемую заготовку;
- известные ключи MIFARE или PWD/PACK, если память защищена;
- резервную запись исходных данных перед любыми изменениями.
Подключите ODRFID к компьютеру, запустите программу, нажмите Подключить и выберите обнаруженный считыватель. Подносите только одну метку: две карты в поле могут мешать выбору и чтению.
Как выглядит работа в ODRFIDKit
ODRFIDKit определяет семейство и UID метки, а затем показывает подходящие для неё инструменты. У MIFARE Classic это выбор сектора, Key A/Key B, таблица 16-байтных блоков и отдельный редактор служебного блока. У Ultralight и NTAG вместо секторов отображаются страницы и конфигурационные области.



Зелёный индикатор рядом с типом карты означает, что метка обнаружена. Цвета ячеек помогают отличать обычные данные от UID, ключей, битов доступа и конфигурации. Перед копированием всё равно ориентируйтесь не только на цвет, но и на номер блока, права доступа и описание конкретного семейства.
Вариант 1. Скопировать UID MIFARE Classic 13,56 МГц
Этот способ подходит, если система использует только четырёхбайтный UID и не проверяет содержимое памяти. Обычная MIFARE Classic имеет заводской UID, который изменить нельзя. Целевой картой должна быть специальная Classic-совместимая заготовка с перезаписываемым нулевым блоком.
Процедура
- Поднесите исходную карту. ODRFIDKit покажет её тип и UID.
- Убедитесь, что UID состоит из четырёх байт — восьми шестнадцатеричных символов.
- Нажмите Копировать UID. Значение попадёт в буфер обмена.
- Уберите исходную карту. При необходимости нажмите Следующая карта, затем поднесите специальную заготовку.
- Выберите сектор 0. Рядом с UID появится инструмент Смена UID.
- Откройте его, вставьте UID исходной карты в поле Новый UID.
- Прочитайте предупреждение, подтвердите принятие риска и нажмите Продолжить.
- Уберите и снова поднесите заготовку. Считайте её ещё раз и сравните полученный UID с исходным.
ODRFID не просто записывает восемь символов в начало памяти. Прошивка читает нулевой блок целевой карты, заменяет UID, пересчитывает контрольный байт BCC и сохраняет остальные заводские данные блока. Поэтому для смены UID следует использовать отдельный инструмент программы, а не переписывать заводской блок (manufacturer block) вручную.
Если кнопка смены UID не появилась или запись завершилась ошибкой, не пытайтесь принудительно записывать блок 0 как обычный блок данных. Скорее всего, карта имеет неизменяемый UID, другой размер идентификатора или несовместимый механизм записи. Неудачная операция с нулевым блоком специальной карты может сделать её нечитаемой.
Вариант 2. Скопировать UID EM4100 125 кГц
Настоящие EM4100/EM4102 — карты только для чтения. Когда говорят о записи или клонировании EM4100, идентификатор записывают в T5557, T5567, T5577 или совместимую микросхему, настроенную на эмуляцию EM4100.
Для этой операции нужен ODRFID-M или ODRFID-E.
Процедура
- Поднесите исходную EM-Marine. В окне появятся тип карты и её пятибайтный UID.
- Нажмите Клонировать. ODRFIDKit запомнит считанный UID и откроет окно программирования.
- Уберите исходную карту.
- Выберите кодирование Manchester или BiPhase и скорость RF/64 или RF/32, требуемые вашей системой и заготовкой.
- Если заготовка уже защищена известным паролем, включите поле Текущий пароль и введите его.
- Чтобы защитить новую метку от случайной перезаписи, можно включить поле Новый пароль. Обязательно сохраните его в надёжном месте.
- Поместите T55xx-заготовку в поле считывателя и только после этого нажмите OK.
- После завершения уберите заготовку, поднесите её снова и проверьте UID.
Текущий пароль целевой заготовки нельзя «прочитать» из исходной EM4100. Если T55xx уже защищена неизвестным паролем, ODRFIDKit не сможет подготовить её к перезаписи. Новый пароль относится к заготовке, а не к копируемому UID.
ODRFID-M/E считывают также HID ProxCard II, но мастер клонирования в ODRFIDKit записывает именно эмуляцию EM4100. Чтение HID Prox не означает, что программа может записать его копию в T55xx.
Вариант 3. Перенести блоки MIFARE Classic
У MIFARE Classic память разделена на секторы, а каждый сектор — на блоки по 16 байт. Последний блок сектора — служебный блок (sector trailer): в нём находятся Key A, биты доступа, служебный байт GPB и Key B. Поэтому копирование данных выполняется посекторно и требует отдельной аутентификации.
Для каждого сектора могут понадобиться два разных набора полномочий:
- ключ исходной карты, которому разрешено читать нужные блоки;
- текущий ключ целевой карты, которому разрешено записывать эти блоки.
Знание ключа от исходной карты не даёт автоматического права записи в заготовку. И наоборот, заводской ключ новой карты не открывает защищённый сектор оригинала.
Сначала прочитайте исходную карту
- Поднесите исходную карту и выберите нужный сектор.
- Выберите Key A или Key B и введите шестибайтный ключ. Для незапрограммированной
карты часто используется
FFFFFFFFFFFF, но это не универсальный ключ. - Нажмите Читать.
- Убедитесь, что программа сообщила об успешном чтении. Предупреждение об ошибке доступа означает, что часть показанных байтов может быть недостоверной.
- Переключите представление таблицы в HEX и сохраните 16 байт каждого пользовательского блока во внешнюю рабочую запись.
- Повторите чтение для всех нужных секторов и ключей.
ODRFIDKit работает как посекторный редактор, а не как мастер полного копирования Classic. При переходе к другой физической карте содержимое таблицы будет заменено результатом нового чтения, поэтому данные исходных блоков нужно зафиксировать заранее.
Затем запишите целевую карту
- Уберите оригинал, нажмите Следующая карта при необходимости и поднесите целевую карту того же семейства и достаточного объёма.
- Выберите соответствующий сектор.
- Введите текущий Key A или Key B целевой карты, которому её биты доступа разрешают запись.
- Нажмите Читать, чтобы получить актуальные права и содержимое целевого сектора.
- Введите сохранённые байты в пользовательские блоки таблицы. Не меняйте строки, которые программа помечает как недоступные для записи.
- Нажмите Применить. ODRFIDKit запишет изменённые блоки и сообщит о тех, которые были пропущены из-за прав доступа.
- Снова нажмите Читать и сравните записанные значения с оригиналом.
- Повторите процедуру для остальных секторов.
В секторе 0 не переносите заводской блок как обычные данные. В нём находятся UID, BCC и заводская информация. Для смены четырёхбайтного UID используйте отдельную процедуру из предыдущего раздела.
Нужно ли копировать служебный блок сектора
Обычно для переноса прикладных данных достаточно копировать только пользовательские блоки, оставляя ключи и права целевой карты без изменений. Это снижает риск заблокировать сектор.
Если целевая карта должна получить те же ключи и биты доступа, откройте редактор Trailer, укажите известные Key A/Key B и требуемую комбинацию прав, а затем нажмите Применить. Перед записью проверьте, каким текущим ключом разрешено изменять трейлер.
Key A нельзя получить простым чтением карты: микросхема использует его для аутентификации, но не возвращает как данные. Значение Key A, показанное после успешного чтения в ODRFIDKit, — это ключ, который ввёл пользователь, а не извлечённый из карты секрет. Key B также может быть недоступен для чтения в зависимости от битов доступа.
Ошибочная комбинация прав способна навсегда закрыть блок или трейлер от изменения. Не копируйте три байта доступа вслепую: используйте редактор, который показывает разрешения на чтение, запись, инкремент и декремент.
Что меняется для MIFARE Plus
MIFARE Plus в SL1 доступна через Classic-совместимый режим, поэтому данные переносятся по той же посекторной схеме. В SL3 ODRFIDKit выполняет отдельную AES-аутентификацию: вместо шестибайтного ключа Classic потребуется известный 16-байтный ключ и совместимая ревизия ODRFID.
Копирование блоков данных не копирует AES-ключи Plus. В SL3 они не являются обычными байтами трейлера сектора, поэтому их нельзя перенести вместе с содержимым строки таблицы. Для исходной и целевой карты нужно отдельно знать ключи, разрешающие чтение и запись. Карты Plus в SL0 и SL2 программа определяет, но редактор переноса памяти для этих уровней не открывает.
Вариант 4. Перенести страницы Ultralight EV1 и NTAG
Ultralight и NTAG хранят данные не в 16-байтных блоках, а в страницах по 4 байта. Начальные страницы содержат UID и заводскую информацию, далее идёт пользовательская память, а в конце расположены конфигурация, PWD/PACK и динамические биты блокировки.
Процедура
- Поднесите исходную метку и дождитесь определения точной модели.
- Если метка защищена, откройте поле пароля и введите известные PWD/PACK.
- Нажмите Читать. Не продолжайте, если чтение остановилось на защищённой области или программа предупреждает о неверных данных.
- Нажмите Сохранить как и сохраните дамп
.mfc. Его можно открыть позже во встроенном эмуляторе ODRFIDKit как эталон. - Отдельно зафиксируйте номера и содержимое пользовательских страниц, которые нужно перенести.
- Поднесите целевую метку той же модели либо совместимую метку с достаточной памятью и прочитайте её.
- Введите данные в пользовательские страницы и нажмите Применить.
- Перечитайте метку и сравните результат с сохранённым дампом.
Не переносите начальные страницы с UID и заводскими байтами: у обычных Ultralight/NTAG они не перезаписываются. Не копируйте без отдельной цели OTP, биты блокировки, счётчики, пароль и конфигурационные страницы. Биты блокировки и блокировка конфигурации могут быть необратимыми, а перенос AUTH0 или PWD способен сразу закрыть часть памяти от дальнейшего чтения.
PWD/PACK ограничивают доступ, но не являются шифрованием радиообмена. Для чтения защищённых страниц пароль нужно знать заранее; ODRFIDKit не подбирает его.
Копирование вручную через AT-команды
ODRFIDKit использует программный интерфейс считывателя, но для типовых операций графическая программа не обязательна. ODRFID-M/N/E принимают текстовые команды через виртуальный COM-порт USB CDC. Так можно перенести один UID, блок или страницу из терминала, а затем автоматизировать ту же последовательность в собственной программе.
| Операция | Команды | Модели |
|---|---|---|
| Смена UID специальной MIFARE Classic | AT+~<UID> | ODRFID-M, ODRFID-N |
| Копирование EM4100 на T55xx | AT+@<UID> | ODRFID-M, ODRFID-E |
| Чтение и запись блока Classic | AT+R<блок>, AT+W<блок>:<HEX> | ODRFID-M, ODRFID-N |
| Чтение и запись страницы Ultralight/NTAG | те же AT+R и AT+W | ODRFID-M, ODRFID-N |
Перед началом включите интерфейс USB CDC, закройте ODRFIDKit и другие программы,
которые держат этот порт, затем откройте его с параметрами 115200, 8N1.
Настройка скорости нужна терминалу, хотя для самого USB CDC она не влияет на
физическую скорость обмена. Каждую команду завершайте CR, LF или CRLF.
Проверьте связь и остановите автоматическое сканирование:
> ATI
Open Development RFID Reader 3.9m ...
S/N ...
OK
> AT+SCAN0
OK
В режимах SCAN1–SCAN3 ручное чтение и запись недоступны. Во всех примерах
ниже сначала используется AT+SCAN0, а в поле считывателя находится только
одна карта. Полное описание ответов и кодов ошибок приведено в
руководстве по AT-командам ODRFID-M/N/E.
Вручную скопировать UID MIFARE Classic
Сначала выберите исходную карту и сохраните её UID:
> AT+i
+UID=8C5BFE0408
OK
В этом ответе 8C5BFE04 — четырёхбайтный UID, а последние 08 — SAK. В
команду смены UID передаётся только UID, без SAK.
Уберите оригинал, поднесите специальную Classic-совместимую заготовку с изменяемым UID и выберите её. Укажите текущий ключ целевого сектора 0, затем запишите сохранённый UID:
> AT+i
+UID=DEADBEEF08
OK
> AT+KAFFFFFFFFFFFF
OK
> AT+~8C5BFE04
OK
Здесь FFFFFFFFFFFF — только пример заводского Key A заготовки. Если её сектор
0 использует другой ключ, передайте фактическое значение. Команда AT+~
сохраняет остальные байты блока 0 и пересчитывает BCC, но длина нового UID
должна совпадать с длиной старого.
Уберите и снова поднесите заготовку, выполните AT+i и убедитесь, что ответ
содержит +UID=8C5BFE0408. Если AT+~ вернула ошибку, целевая карта не
поддерживает этот способ смены UID, имеет другую длину UID либо не принимает
указанный ключ. Не заменяйте эту операцию прямой записью блока 0.
Вручную перенести блок MIFARE Classic
Пример переносит пользовательский блок 4. Сначала выберите оригинал, задайте ключ исходного сектора и прочитайте данные:
> AT+SCAN0
OK
> AT+i
+UID=8C5BFE0408
OK
> AT+KA112233445566
OK
> AT+R4
+DATA 4:00112233445566778899AABBCCDDEEFF
OK
Уберите оригинал и поднесите целевую карту. Заново выполните AT+i и задайте
уже текущий ключ целевой карты — он может отличаться от ключа оригинала:
> AT+i
+UID=04A1B2C308
OK
> AT+KAFFFFFFFFFFFF
OK
> AT+W4:00112233445566778899AABBCCDDEEFF
OK
> AT+R4
+DATA 4:00112233445566778899AABBCCDDEEFF
OK
Последнее чтение является обязательной проверкой. Для Key B вместо AT+KA
используйте AT+KB. Не применяйте этот пример к блоку 0 или sector trailer.
Перед копированием нескольких блоков составьте явный список пользовательских
адресов и отдельно проверьте права каждого сектора.
У Ultralight и NTAG последовательность та же, но размер страницы составляет
4 байта. Сначала выполните AT+S и убедитесь, что ответ содержит BS=4.
Например, страницу 8 можно прочитать и записать так:
> AT+R8
+DATA 8:11223344
OK
> AT+W8:11223344
OK
Не переносите этим способом UID, OTP, lock bits и конфигурационные страницы.
Если метка защищена, предварительно задайте известный четырёхбайтный пароль
командой AT+KU<8 HEX> и проверьте PACK командой AT+KP.
Вручную скопировать EM4100 на T55xx
На ODRFID-M или ODRFID-E выберите исходную EM4100. В ручном ответе после пятибайтного UID присутствует ещё один служебный байт:
> AT+SCAN0
OK
> AT+i
+UID=4201020304FF
OK
Копируемый UID — 4201020304; завершающий FF в команду записи не входит.
Уберите оригинал и положите в поле чистую T5557/T5567/T5577-совместимую
заготовку.
Перед записью задайте кодирование и скорость командой AT+c<код>,<скорость>.
0,0 означает Manchester и RF/64, 0,1 — Manchester и RF/32, 1,0 —
BiPhase и RF/64, 1,1 — BiPhase и RF/32. Текущие параметры возвращает
AT+c?. Для стандартного варианта EM4100 с Manchester и RF/64 сеанс выглядит
так:
> AT+c0,0
OK
> AT+@4201020304
OK
Команда AT+@ рассчитана на незащищённую заготовку. Чтобы одновременно
установить новый 32-битный пароль, используется
AT+x<пароль>,<UID>, например:
> AT+xA1B2C3D4,4201020304
OK
Пароль ограничивает перезапись T55xx, но не шифрует UID. Сохраните его: для
снятия защиты понадобится AT+uA1B2C3D4, а неизвестный пароль считыватель не
подбирает.
Для программирования T55xx ответ OK означает, что команда принята, но не
доказывает, что заготовка действительно записалась. Уберите её из поля,
поднесите снова, выполните AT+i и сравните первые десять HEX-символов UID с
оригиналом. Если UID не совпал, проверьте совместимость заготовки, её текущую
защиту, положение на антенне, кодирование и скорость.
Python: скопировать один блок MIFARE Classic
Ниже — законченный пример на pyserial. Он читает пользовательский блок 4 с
исходной карты, просит заменить карту, показывает старое содержимое цели,
запрашивает явное подтверждение, записывает данные и перечитывает блок.
Установите зависимость:
python -m pip install pyserial
Укажите порт и ключи обеих карт в начале скрипта:
import re
import serial
PORT = "/dev/ttyACM0" # например, "COM4" в Windows
BLOCK = 4 # пользовательский блок, не block 0 и не trailer
SOURCE_KEY = "112233445566"
TARGET_KEY = "FFFFFFFFFFFF"
DATA_RE = re.compile(
rf"^\+DATA {BLOCK}:([0-9A-Fa-f]{{32}})$"
)
def read_line(reader):
while True:
raw = reader.readline()
if not raw:
raise TimeoutError("Считыватель не ответил")
line = raw.decode("ascii", errors="replace").strip()
if line:
return line
def command(reader, text):
reader.write((text + "\r\n").encode("ascii"))
payload = []
while True:
line = read_line(reader)
if line == "OK":
return payload
if line == "ERROR":
details = "; ".join(payload) or "ERROR"
raise RuntimeError(f"{text}: {details}")
payload.append(line)
def select_card(reader):
payload = command(reader, "AT+i")
uid_line = next(
(line for line in payload if line.startswith("+UID=")),
None,
)
if uid_line is None:
raise RuntimeError("Карта не найдена")
print("Выбрана карта, UID+SAK:", uid_line.removeprefix("+UID="))
info = command(reader, "AT+S")
if not any(",BS=16," in line for line in info):
raise RuntimeError("Ожидалась карта с 16-байтными блоками")
def set_key_a(reader, key):
if not re.fullmatch(r"[0-9A-Fa-f]{12}", key):
raise ValueError("Ключ должен содержать 12 HEX-символов")
command(reader, "AT+KA" + key.upper())
def read_block(reader):
payload = command(reader, f"AT+R{BLOCK}")
for line in payload:
match = DATA_RE.fullmatch(line)
if match:
return match.group(1).upper()
raise RuntimeError(f"В ответе нет данных блока {BLOCK}: {payload}")
with serial.Serial(
PORT,
115200,
timeout=2,
write_timeout=2,
) as reader:
reader.reset_input_buffer()
command(reader, "AT+SCAN0")
input("Поднесите исходную карту и нажмите Enter...")
select_card(reader)
set_key_a(reader, SOURCE_KEY)
source_data = read_block(reader)
print("Исходные данные:", source_data)
command(reader, "AT+SELECT=") # снять выбор исходной HF-карты
input("Уберите оригинал, поднесите целевую карту и нажмите Enter...")
select_card(reader)
set_key_a(reader, TARGET_KEY)
target_data = read_block(reader)
print("Содержимое цели до записи:", target_data)
answer = input(f"Записать блок {BLOCK}? Введите YES: ")
if answer != "YES":
raise SystemExit("Запись отменена")
command(reader, f"AT+W{BLOCK}:{source_data}")
verified_data = read_block(reader)
if verified_data != source_data:
raise RuntimeError(
f"Проверка не пройдена: {verified_data} != {source_data}"
)
print("Готово: блок записан и проверен чтением")
Этот пример намеренно копирует только один обычный блок. Для нескольких секторов нужно хранить отдельные ключи, исключать block 0 и все sector trailer, а после каждой записи сравнивать данные. Автоматизацию смены UID и программирования T55xx лучше строить по той же схеме: сначала прочитать и проверить источник, затем запросить подтверждение цели и обязательно перечитать результат.
Как понять, что копия действительно работает
Совпадение UID на экране — только первая проверка. После записи:
- уберите метку из поля и поднесите снова;
- перечитайте UID, каждый перенесённый сектор или страницу;
- проверьте карту в целевой системе;
- сохраните отдельно результат проверки и использованные ключи;
- до завершения испытаний не изменяйте оригинал.
Если UID совпал, но система отвергает копию, она может проверять память, счётчик, тип микросхемы, криптографический ответ или запись в серверной базе. Если данные совпали, но UID отличается, приложение может использовать UID как часть ключа или индекса. Это не ошибка считывателя: просто конкретная система проверяет больше одного признака.
Что нельзя скопировать одной кнопкой
- заводской UID обычной MIFARE, Ultralight или NTAG;
- неизвестные Key A/Key B, AES-ключи или PWD;
- защищённые блоки, на чтение которых нет разрешения;
- блоки целевой карты, на запись которых не дают права её текущие биты доступа;
- криптографическое состояние DESFire и других защищённых приложений;
- необратимые счётчики и аппаратные особенности оригинальной микросхемы;
- HID ProxCard II с помощью EM4100-мастера ODRFIDKit.
Для MIFARE Ultralight C и DESFire настольная ODRFIDKit показывает UID, но не предоставляет редактор памяти. MIFARE Plus в защищённом SL3 требует известных 16-байтных AES-ключей и совместимой ревизии считывателя.
Какой считыватель выбрать
| Задача | Модель |
|---|---|
| MIFARE Classic, Plus, Ultralight и NTAG 13,56 МГц | ODRFID-N |
| Карты 13,56 МГц и EM4100/T55xx 125 кГц на одном рабочем месте | ODRFID-M |
| Чтение EM-Marine/HID Prox и программирование T55xx в режиме EM4100 | ODRFID-E |