Основы NFC и интеграция с PC/SC

от автора

Сегодня расскажу, что такое NFC с техническими подробностями, чтобы это могло быть полезным всем, кто сталкивается с этим в разработке прикладного ПО, а также затрону тему интеграции доступа к NFC меткам через PC/SC считыватели. Последний пункт относится это к десктопным системам. На мобильных платформах всё сложней, потому что, как правило, нет общей реализации PC/SC, а доступ реализован через специфичный для данной платформы API.

 Технические основы NFC

В основе лежит электромагнитная индукция, открытая Фарадеем ещё в 1831 году. В обмене участвуют две стороны: активная, которая излучает переменное поле, и пассивная, в антенне которой поле наводит ток.

Используемая полоса частот: 13.56 MHz  +/-14 kHz. Она относится к категории ISM (industrial, scientific and medical). Использование регулируется по упрощенной схеме.

Параметры в микросхемах подобраны так, чтобы энергии поля хватило навести в пассивной антенне ток, достаточный для питания микросхемы, выполнения вычислений, и передачи ответного сигнала достаточной силы обратно ридеру.

NFC объединяет несколько технологий: NFC-A, NFC-B, NFC-F и NFC-V. Что это такое, опишем ретроспективно.

В 1990х годах компания Philips (ныне NXP) разработала первые образцы карт и ридеров (и сам протокол тоже) для бесконтактного обмена данными. Это были карты памяти MIFARE с функцией чтения/записи. Линейка активно развивается до сего дня и содержит множество продуктов.

В то же время группа европейских специалистов поняла, что, во-первых, протокол Philips проприетарный, а во-вторых, плохо подходит для «тяжелых» карт с микропроцессором, которые выполняют сложные вычислительные операции и разработали модифицированную версию бесконтактного протокола, оптимизировав энергетические характеристики сигнала.

Обе эти версии стали частью одного стандарта: ISO/IEC 14443. Первый протокол стал называться «тип А», а второй – «тип В».

Азиатский рынок не устроили оба протокола. По оценке специалистов, для высоконагруженных транспортных систем необходимо, чтобы вся транзакция взаимодействия карты и терминала укладывалась в 200 мс. Иначе это создаст задержки пассажиропотока. ISO14443 таких показателей достичь не мог. Sony разработала свой вариант: FeliCa. Он стал национальным стандартом JIS: X6319. Была инициатива протащить его в ISO 14443 как тип С, но им отказали.

Параллельно со всем этим был разработан протокол и карты памяти для работы на увеличенной дистанции до 1,5 метра (ISO 14443 подразумевает максимум 10 см, хотя это напрямую не прописано). Они получили название vicinity cards (стандарт ISO/IEC 15693). Пример коммерческого продукта: метки NXP ICODE. Получились RFID чипы из немного другой области: для логистики и торговли.

Поскольку в основе этих протоколов лежит общая физика, в начале нулевых их объединили одним стандартом, расширив возможности обмена на верхних уровнях (чтобы не только обмен типа «карта-устройство» был возможен, но и «устройство-устройство»). Получилась спецификация Near Field Communication, а четыре протокола стали четырьмя технологиями:

·       NFC-A — протокол ISO 14443, тип А

·       NFC-B — протокол ISO 14443, тип B

·       NFC-F — протокол FeliCa

·       NFC-V — протокол vicinity cards

Основной областью применения NFC стали мобильные устройства.

Хоть на нижних уровнях NFC, вроде, и такой же, как и ISO 14443, но в стандарте спецификация нижних уровней повторена. Это позволило адаптировать протокол к миру мобильных устройств. Например, в ISO14443 говорится про диапазон напряженности электромагнитного поля, излучаемого ридером, когда речь идёт о дальности взаимодействия (единицы измерения — А/м), а в NFC диапазон указан в мм (было раньше до 10 мм, а в Release 15 стало 20 мм).

В своей практике я пересекался только с первыми двумя технологиями, поэтому далее речь пойдет только о них и в контексте ISO 14443.

На Сайте developer.android.com считаются синонимами термины «технология NFC-A/B» и «ISO 14443, тип А/В». Я буду считать также.

Протоколы ISO 14443 A и B

Придется немного погрузится в описание обоих протоколов, потому что спецификация PC/SC на это опирается, и через пользовательское ПО до некоторых данных/параметров можно добраться, а иногда кое-что можно и настроить.

Сами карты в стандарте ISO называются PICC (proximity integrated circuit card), а ридеры — PCD (proximity coupling device).

В первой части ISO 14443 речь идет о требованиях к антеннам PICC. В какой корпус антенну встроить – уже не важно, поэтому в NFC стали использовать более общий термин — tag (метки). В ISO 14443 все антенны классифицированы по размеру от класса 1 (самые большие, под форм-фактор ID-1 и загранпаспорт) до класса 6 (размер с монету). Это позволяет изготавливать NFC метки в виде почти чего угодно, лишь бы антенна поместилась. В NFC метки классифицированы по-другому:

·       Тип 1: ныне устаревшие карты памяти, родственные типу А, без механизма антиколлизии (т.е. в поле должна быть строго одна метка). В качестве примера обычно приводят чип Topaz512.

·       Тип 2: карты памяти типа NXP MIFARE Ultralight и NXP NTAG.

·       Тип 3: карты FeliCa

·       Тип 4: чипы, полностью соответствующие ISO 14443-4. Например, микропроцессорные карты, а также NXP DESFire.

·       Тип 5: чипы iCode.

Забавно, что одни из самых распространенных типов карт MIFARE Classic не относится ни к одному из этих типов (non-NFC Forum tag type), но телефоны их прекрасно поддерживают. В основном, за счет того, что в каждый телефон встроен специальный чип от NXP.

Метки типа 4, как правило, поддерживают только один протокол (А или B), но бывают варианты, когда их можно переключить, но это делается на этапе производства. Ридеры, в основном, поддерживают оба протокола сразу.

В стандарте предусмотрена возможность активировать сразу несколько однотипных меток сразу в одном поле и работать с ними одновременно. Для этого используется механизм разбора коллизий. Коллизия — это когда ридер передает одну команду, а отвечают все метки сразу. После процедуры антиколлизии отвечает только та метка, кому передали команду. Ридеры PC/SC антиколлизию поддерживают, но соединение держат только с одной меткой.

Работа по обоим протоколам состоит из следующих этапов:

1.     Инициализация и антиколлизия;

2.     основной рабочий этап;

3.     деактивация.

На первом этапе происходит «включение» микросхемы и приведение её в рабочее состояние.

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

На этом этапе ридер узнаёт уникальный идентификационный номер микросхемы. Для протокола А это UID, а для В — PUPI (pseudo unique PICC identifier). Размер PUPI всегда четыре байта, а для UID есть варианты. Отмечу, что в основе процедуры антиколлизии протокола А лежит свойство уникальности UID. Это первый важный момент, а второй — это то, что некоторые ИТ системы полагаются на его уникальность при обеспечении безопасности, а некоторые наоборот – на НЕуникальность. Неудивительно, что NXP уделяет особое внимание вопросам поддержки UID. Доступные форматы UID:

1.     UID = [UID0, UID1, UID2, UID3] — четырехбайтовый (single size). Возможные значения UID0 регламентированы:

a.     UID0=08 — остальные три байта принимают случайное значение при каждой подаче питания на микросхему (Random UID). В рамках одной сессии меняться не должен.

b.     UID0=x0…x7, 18…78, 98…E8, x9…xE — зарезервированы для продуктов линейки MIFARE.

c.     UID0= xF — фиксированный, но не уникальный UID. Значит, что может существовать еще одна или несколько карт с таким же номером.

d.     UID0=F8 — зарезервировано

e.     UID0=88 — не встречается, поскольку используется как технологическое значение для выполнения этапа антиколлизии.

f.      Остальные значения — просто фиксированный четырехзначный номер.

2.     UID = [UID0, …, UID6] — семибайтовый (double size). Байт UID0 хранит код производителя из диапазона 00…80. Значение 04 указывает на NXP. Остальные 6 байт используются самим производителем по своему усмотрению.

3.     UID = [UID0, …, UID9] — десятибайтовый (triple size). Аналогично с предыдущим пунктом байт UID0 хранит код производителя. Есть ли в обиходе метки с таким длинным UID, мне неизвестно.

В ряде случаев фиксированный UID/PUPI является угрозой, потому что предоставляет легкий и бесплатный способ отслеживать кого-либо/чего-либо, поэтому в следующих случаях применяется только Random UID/PUPI:

1.     в идентификационных документах типа загранпаспорта и им родственных (см. спецификацию ICAO Doc 9303).

2.     Смартфоны в режиме эмуляции карты через NFC (Android и iOS).

Для микропроцессорных карт инициализация NFC-A заканчивается командой запроса ATS (Request Answer-To-Select). ATS — это своего рода аналог контактного ATR. Он также состоит из коммуникационной части и исторических байт. Для NFC-B и MIFARE ничего похожего на ATS не существует.

Основной рабочий этап и деактивация для обоих протоколов одинаковые (ISO 14443, часть 4). Полезная нагрузка I-блоков — это команды APDU (для меток типа 4). Через PC/SC интерфейс как правило NFC-карты видны как карты с протоколом T=1, потому что правила обмена полезной нагрузкой весьма схожи с контактным T=1. Распространен под названием T=CL.

Для полноты картины отмечу, что ISO 14443 часть 4 в NFC используется только для обмена с картой, а обмен типа «устройство-устройство» использует другой протокол: Logical Link Control Protocol (LLCP). В принципе, они похожи, но форматы блоков разные. LLPC — протокол транспортный, а поверх него используется протокол прикладного уровня — SNEP (Simple NDEF Exchange Protocol). Он как раз и позволяет обмениваться бинарными данным в формате NDEF.

 Интеграция с PC/SC

Есть спецификация «Interoperability Specification for ICCs and Personal Computer Systems» (PC/SC), где описывается взаимодействие смарт-карт с компьютерами посредством ридера (IFD, interface device). Вопросы охватывают широкий диапазон, начиная от архитектуры, заканчивая конкретными функциями API и их аргументами. Особое внимание уделено интеграции карт ISO 14443.

На уровне SCard-функций взаимодействие с бесконтактными картами точно такое же, как и с контактными. Каких моментов касаются отличия?

Момент 1

Откуда берется ATR? В силу особенностей протокола в карте его нет, а в прикладном ПО он уже есть (из SCardStatus или SCardGetAttrib). Он берется из прошивки ридера. Подавляющее большинство ридеров сейчас работают через USB, а для них используется протокол CCID. Если посмотреть на форматы его команд, то можно увидеть, что ATR приходит в компьютер уже в готовом виде. По факту ридер может вернуть всё, что захочет, но в части 3 PC/SC целый раздел посвящен правилам формирования ATR для карт ISO 14443. В целом ридеры этому следуют, поэтому все-таки повторяемость ATR от ридера к ридеру сохраняется, но есть и исключения.

Вывод: для одной и той же карты разные ридеры могут вернуть разные бесконтактные ATR.

При этом между холодным и теплым ATR нет разницы, потому что понятия холодный и теплый сброс в отношении T=CL бессмысленны.

Момент 2

Доступ к UID/PUPI, который использовался на этапе инициализации протокола. Эти данные низкоуровневые и получить их можно через команду Pseudo APDU вида

CLA:FF INS:CA P1:00 P2:00 Le:00

Момент 3

Историческая часть ATS (тип А) появляется в сгенерированном ATR, но можно и запросить:

CLA:FF INS:CA P1:01 P2:00 Le:00

Момент 4

Ридер через атрибуты (см. SCardGetAttrib) может указывать частоту протокола (Default CLK, Current CLK, Max CLK) 13560 и ряд других менее интересных характеристик (Current D, Current FWT, …)

Момент 5

Есть команда для переключения протоколов (тип А или В), поддерживаемых самим ридером, а также задания и получения множества сопутствующих параметров (бодовая скорость, таймаут ожидания фрейма, размеры фрейма, …)

CLA:FF INS:C2 P1:00 P2:02 Lc:xx Data: xx … xx

Момент 6

PC/SC допускает существование мультислотового ридера, т.е. кладешь в поле одного ридера несколько карт и они все видны в ПО. Такого никогда не встречал. Все-таки концепция «один ридер — один бесконтактный слот» является доминирующей.

На самом деле все моменты, перечисленные выше — красивая теория, а в жизни каждый разработчик ридера пишет ту прошивку, которая ему нравится, и ничто не может его заставить это соблюдать, поэтому полагаться на что-то тяжело. Всегда найдется ридер, который или не тот ATR вернул, или какую-то Pseudo APDU не поддерживает, или только по протоколу типа А работает. В конечном счете надо смотреть datasheet на конкретный ридер.

ссылка на оригинал статьи https://habr.com/ru/articles/1064404/