Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Данная статья будет полезна тем, кто начинает работу с карт-принтерами(Evolis Primacy и Smart-51) и кодировкой NFC карт типа Mifare Classic и Mifare DESFire EV2. В первой части мы опишем общее впечатление от работы с карт-принтерами, а также проблемы с которыми нам пришлось столкнуться. Во второй части планируется показать больше практической части: код, советы по эксплуатации.
1. Как появилась задача
Мы занимаемся разработкой системы электронного билетирования, которая включает в себя работу с NFC картами. Каждая NFC карта обладает понятным для пользователя Номером, и индивидуальным ID. Номер должен быть напечатан на карте, а ID записан в NFC чип. Одной из поставленных задач было налаживание стабильного производства транспортных карт.
На первом этапе задача была решена самым простом способом — принты с Номерами печатаются поставщиком NFC карт, а ID записываются нами при помощи настольных считывателей, специального програмного обеспечения и человека. После получения карт от поставщика требуется зарегистрировать карту в системе и связать ID и Номер друг с другом. В качестве настольного считывателя мы использовали Z-2 Reader[1].
Процесс выглядел примерно таким образом:
- Оператор берёт в руки карту. На карте уже напечатан её номер, но требуется регистрация карты в системе и запись ID в NFC чип
- Оператор кладет карту на Z-2 Reader и регистрирует Номер в системе электронного билетирования путем ручного ввода Номера карты. Для связки и регистрации происходит вызов HTTPS API
- Оператор берёт следующую карту и проделывает все ещё раз
Простое и быстрое решение с одним маленьким недостатком. Влияние человеческого фактора порождает фантомные карты, у которых Номер напечатанный на карте не соответствует связке ID-Номер в базе данных системы.
Так и родилась следующая постановка задачи: Требуется печатать Номер, записывать ID и регистрировать NFC карты в системе атомарно и с минимальным участием человека.
В данной статье мы опишем все оборудование, с которым работали, и все подводные камни. В конце постараемся сказать, какое оборудование нам кажется лучше.
1.1. NFC карты
Мы рассматривали NFC карточки MIFARE Classic 1K и MIFARE DESFire EV2. MIFARE Classic наиболее распространённые и наиболее уязвимые для копирования. Однако они продолжают пользоваться популярностью в таких местах как университеты и общественный транспорт. При обращении с денежными потоками необходимо более надёжное решение. Поэтому альтернативой стали карты MIFARE DESFire EV2. Это один из последних типов карточек, которые используют алгоритмы шифрования DES, TDES(2KTDES, 3KTDES), AES [2, 3]. Кратко о каждой карте:
MIFARE Classic
Память карты представляет собой сектора и блоки. Первой единицей памяти является сектор. Всего на карте 16 секторов, в каждом из которых есть 4 блока данных. Память каждого блока составляет 16 байтов. Для считывания и/или записи данных считывателю необходимо авторизоваться в секторе. Один специальный блок в каждом секторе, trailer block, предназначен для хранения ключей. В первую очередь, для работы с сектором нужно авторизоваться в trailer блоке. Trailer block также хранит 16 байтов: 6 байтов на ключ типа A, 4 байта на access rights, 6 байтов на ключ типа B.
На рисунке 1[4] наглядно показаны сектора, блоки и ключи.
Рисунок 1 — Устройство памяти в Mifare Classic
MIFARE DESFire
Устройство карты напоминает файловую систему. Состоит карта из приложений и файлов. На карте есть основное приложение(application) с id – 000000(0x00, 0x00, 0x00). Внутри основного приложения можно создать новое приложение и внутри него создать файлы с данными. Характеристика карт DESFire представлена на рисунке 2[5]. Каждому приложению присваиваются свои ключи доступа к файлам приложения.
Рисунок 2 — Характеристики карт Mifare DESFire
1.2. Принтеры как решение
Для выполнения поставленной задачи используются специальные карт-принтеры. На данный момент есть много разных компаний, поставляющих данные принтеры. Например: Evolis, Smart, Zebra, Datacard и др. Мы использовали принтеры Evolis Primacy и Smart-51. У данных принтеров в основе работы есть много общего: оба используют для печати ленточные кассеты и имеют похожий принцип чистки. Также есть и различия — разные кодировщики NFC. Оба принтера в зависимости от потребностей заказчика могут дополняться элементами или заменяться.
Программаторы для NFC карточек опираются на стандарты ISO/IEC 14443A и ISO/IEC 7816-4 для DESFire, ISO/IEC 14443 Type A для Classic. Однако в зависимости от производителя программаторы могут либо принимать нативные команды по стандартам, либо обертывать нативные команды в специфичные для конкретного программатора. Мы столкнулись и с тем, и с другим.
Evolis Primacy | Smart-51 | |
---|---|---|
Печать | Для печати используется лента (цветная или монохромная). Поставляется целая ленточная кассета. | Для печати используется лента (цветная или монохромная). Поставляется только лента, кассета одна и идет с самим принтером. В комплекте с лентой идет чистящий ролик. |
Кодировщик | Кодировщик компании Elyctis. Прост в использовании, т.к. поддерживает взаимодействие с дефолтными библиотеками Windows для общения с NFC картами, winscard. | Кодировщик компании DUALi. Техподдержка предоставляет специальный SDK для работы с кодировщиком. |
Чистка | Для сохранения принтера в рабочем состоянии, ему требуется постоянная чистка. Есть два типа чистки периодическая (после каждой 1000 карт) и расширенная (после 5000 карт). Соблюдение графика чистки является обязательным условием в гарантийном соглашении. | Чистка требуется после использования печатной ленты. В зависимости от типа ленты и размера картинки для печати, чистка потребуется после 2-4 тыс. карт. |
Корпус | Пластиковый корпус позволяет принтеру быть довольно лёгким. К внутренностям можно легко подобраться, т. к. с обеих сторон стенки принтера открываются. | Металлический корпус делает принтер надёжным для эксплуатации. Некоторые внутренности можно посмотреть только при открытии верхней крышки. |
Софт | Поставляется со специальным софтом «Evolis Print Center» и CardPresso. Первый нужен для настроек принтера, оснащён разными помощниками. Второй софт позволяет быстро опробовать возможности принтера для печати и кодировки. | Отдельный софт для контроля принтера не требуется. Достаточно свойств принтера в списке устройств Windows. Поставляется с программой SmartID для печати и кодировки. |
Таблица 1 — Сравнение Evolis Primacy и Smart-51
2. Эксперименты
В целом работу с принтерами можно разделить на несколько частей: общение с техподдержкой, изучение взаимодействия карт и кодировщиков, печать.
2.1. Впечатление от технической поддержки
Работа с принтерами включала в себя постоянное общение с техподдержкой, т. к. нам необходимо было написать собственный софт. В обоих случаях мы общались больше с дистрибьюторами компаний в нашей стране и соседних стран.
Дистрибьюторы Evolis были по большей части всегда на связи. Однако почти сразу специфика вопросов показала необходимость общения с представителями Evolis. К сожалению, нам их контакты не дали и приходилось обмениваться сообщениями через дистрибьютора. Однако это коснулось только вопросов печати, по вопросам кодировки нам дали почту представителя Elyctis. Общение на прямую с Elyctis сильно упростило процесс кодировки. Чисто технически мы сразу понимали друг друга и не было недопонимания. В случае с печатью и примерами кода для Evolis Primacy, общение в какой-то момент заходило в тупик. В основном негативное впечатление составили моменты, когда у нас не работали примеры двусторонней печати и приходилось долго это доказывать. Доходило до записей процессов печати на видео, после чего последовали более результативные советы со стороны Evolis.
Одним из последних вопросов техподдержке Evolis был вопрос о подключении принтера посредством Ethernet. На данный момент мы подключаем принтер по USB к ноутбуку, что терпимо при наличии 1-2 принтеров. Ответы все ещё ждём. Однако от Elyctis уже был получен ответ, что их кодировщик для принтера Evolis Primacy не предусматривает сетевое подключение.
Общение с техподдержкой Smart-51 также сводилось к общению с представителями самой компании через дистрибьютора. В самом начале все шло гладко. Когда дело дошло до кодировки карт типа Mifare DESFire, начались проблемы. Сложности вызывали специфичные команды, которых не встретишь в интернете. По этой причине приходилось просто копировать какие-то части из рабочего кода, предоставленного производителем как пример. Однако бездумное копирование до добра не доводит. В итоге две недели было потрачено на объяснение ошибки производителю, на чьей стороне сидел явно человек не сильно приближенный к тонкостям работы системы, но держащий при себе общую документацию. Неприятный осадок остался, а ведь начиналось очень хорошо.
Общение через дистрибьютора не имеет никаких плюсов, сплошные минусы. Например:
- Задержки ответов, т. к. ответственный человек на стороне дистрибьютора может быть занят другими делами или выходить в отпуск.
- Когда дистрибьютор находится в другой стране, то это дополнительные праздничные дни, следовательно, не рабочие. В случае со Smart-51 общение происходило при участии людей из 3-х стран.
- Ответы не пересылаются. Текст ответа вставляется в новое письмо от дистрибьютора. По этой причине порой вложенные файлы теряются и не доходят сразу.
- Нет чёткой уверенности, что ваше сообщение дошло до производителя без изменений.
Ниже приведена таблица с количеством писем, что составили общение с техподдержкой. В основном вопросы к Evolis и Smart были примерно одинаковые. Например, "Почему печать не однородного цвета? Есть ли у вас примеры кода на C# или Java?" и более специфичные вопросы о том почему что-то не работает так как ожидалось.
Evolis | Elyctis | Smart-51 | |
---|---|---|---|
Кол-во писем | 97 | 37 | 61 |
Таблица 2 — Сравнение количества писем по email с техподдержкой
2.2. Кодировка
Общение со считывателем происходит посредством APDU команд. APDU(Application Protocol Data Unit) это стандартный формат общения карты и считывателя. В данной статье будут описаны основные APDU команды для MIFARE Classic и MIFARE DESFire.
Название | Размер | Описание |
---|---|---|
CLA | 1 byte | Class байт |
INS | 1 byte | Instruction байт |
P1 | 1 byte | Параметр 1 |
P2 | 1 byte | Параметр 2 |
Data Length | 1 byte | Размер передаваемых данных |
Data | ... | Передаваемые данные |
Expected Data Length | 1 byte | Размер ожидаемых данных в ответе |
Таблица 3 — Формат APDU команд
Название | Размер | Описание |
---|---|---|
SW1 | 1 byte | Общий код успеха или ошибки |
SW2 | 1 byte | Детальный код ошибки |
Data | ... | Возвращаемые данные |
Таблица 4 — Формат APDU ответа
Описание всех возможных ответных кодов можно посмотреть здесь[6]. С устройством общения карт со считывателем можно ознакомиться по ссылке [7].
Краткий алгоритм кодировки выглядит следующим образом:
- Получить UID карты. Это уникальный номер, прошивается поставщиком и не изменяется.
- Считать данные из каждого сектора:
2.1 Авторизоваться в секторе, используя дефолтный ключ (0x00 или 0xFF)
2.2 Считать данные трех блоков данных - Если считанные данные пустые, то переходим к записи данных
3.1 Авторизоваться в секторе, используя дефолтный ключ (0x00 или 0xFF)
3.2 Записать данные в три блока данных сектора
3.3 Создать новый ключ, основываясь на UID карты
3.4 Заменить ключ авторизации в trailer block на новый ключ.
2.2.1. Elyctis
В принтере Evolis используется ELYCTIS CL reader. С помощью библиотеки WinSCard(С++ и С#) и jnasmartcardio(java) можно без проблем взаимодействовать со считывателем. В целях быстрого создания софта с довольно простым интерфейсом было решено писать код на С#. В основном наша команда пишет код на Java, что сделало переход на C# менее болезненным. Также в пользу C# говорил тот факт, что ОС Windows больше подходит для работы с принтерами.
Ниже в таблице представлены примеры нативных APDU команд, которые принимаются Elyctis считывателем.
Описание | Данные | APDU |
---|---|---|
Получение UID карты | - | 0xFF 0xCA 0x00 0x00 0x00 |
Загрузка ключа авторизации в память считывателя | 6-ти байтовый ключ | Пример загрузки дефолтного ключа. 0xFF 0x82 0x20 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 |
Авторизация | Номер блока авторизации сектора(3-ий блок сектора) и тип ключа(А — 0x60 или B — 0x61) | Пример авторизации в сектор 1. Номера блоков данного сектора 4-7, trailer блок под номером 7. 0xFF 0x86 0x00 0x00 0X05 0x01 0x00 0x07 0X60 0x00 0x00 |
Чтение данных из блока | - | Пример чтения данных из блока 4 (1-ый блок сектора 1). Номер сектора заносится в параметр 2. 0xFF 0xB0 0x00 0x04 0x00 0x10 |
Запись данных в блок | 16 байтов данных | Пример записи данных в блок 4. 0xFF 0xD6 0x00 0x04 0x10 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x11 0x22 0x33 0x44 0x55 0x66 0x77 0x88 0x00 |
Таблица 5 — Примеры APDU команд для Mifare Classic
Убедившись в успешности кодировки карт типа Mifare Classic, мы перешли на команды для DESFire. По ссылке[8] можно найти простые примеры команд с объяснениями. Однако уже на команде авторизации мы столкнулись с интересным поведением считывателя. Если кратко, то считыватель совершал полную авторизацию сам. Оказалось, что техподдержка Elyctis предоставила нам специальную прошивку, включавшую в себя easyDESFire intelligence. Необходимо только определить какой алгоритм шифрования использует считыватель. В нашем случае это был 3DES.
В обычных случаях авторизация осуществляется путем обмена несколькими сообщениями.
- Отправляем APDU команду для авторизации: 0x90 0x0A 0x00 0x00 0x00 0x00.
- В зависимости от алгоритма в ответ на команду приходит массив из 8 случайных байтов закодированных ключом карты, обозначим как RandBEnc.
- Расшифровываем RandBEnc и делаем сдвиг байтов влево. Обозначим полученный результат как RandBLeft.
- Генерируем на своей стороне массив из 8 случайных байтов, RandA.
- Группируем RandA и RandBLeft, зашифровываем ключом карты и отправляем полученный массив из 16 байтов.
- Получаем в ответ ключ сессии, тем самым авторизовавшись в приложении на карте.
Более подробно с процессом авторизации можно ознакомиться здесь[9]. Также очень полезен код с гитхаба[10].
Во время кодировки возникали проблемы с применением команд из источника[8]. С помощью техподдержки Elyctis мы получили необходимые команды, подходящие для easyDESFire intelligence.
За время кодировки на Elyctis, выяснилась одна большая проблема считывателя — задержка связи. Довольно часто сигналы до считывателя не доходят, поэтому одну и ту же команду порой нужно отправлять по несколько раз. Такое поведение реже, но все же замечается при отправке команд для печати. В результате отправка всех команд проходит в цикле, до успешного выполнения.
2.2.2. DUALi
Производитель дает свое SDK для работы с DUALi кодировщиком. На этапе работы с Mifare Classic команды для чтения и записи можно было взять из шаблонного кода, который дали нам дистрибьюторы. Примеры были на языках C++, Visual Basic, Java. Однако полностью скомпилировать код получилось только на C++. При первом запросе примера кода на C# мы получили отказ, а точнее, что такого у дистрибьютора нет. Уверенных программистов на C++ в нашей команде нет, так что написание всего кода сильно осложнялось довольно простыми вещами. Например:
- Работа с массивами
При передаче массива как параметр в функцию, мы не передавали размер массива. Для определения длинны массива использовалась функция sizeOf(). Однако функция выдавала постоянно размер 4, вне зависимости от реального размера массива. Данное поведение было не сразу зафиксировано, т. к. некоторые массивы действительно были размера 4. - Настройка всех библиотек
Много боли было испытанно при установке всего необходимого окружения. Мы слишком привыкли к таким вещам как maven и apt(в Ubuntu). Наша программа должна была вызывать АПИ бэкенда посредством HTTP запросов и шифровать данные в Base64. Для этого было решено использовать библиотеки libcurl и openssl. Написание самой программы происходило в среде Microsoft Visual Studio. Дольше всего провозились с установкой libcurl.
Само SDK представляет собой dll библиотеку, написанную на C++. Благодаря примеру кода мы относительно быстро написали программу взаимодействия с картой Mifare Classic. Как уже упоминалось выше, команды APDU для DUALi были очень специфичны, а именно первые два байта никак не сходились с теми, которые можно встретить в интернете. Из-за этого приходилось слепо копировать их, т. к. в принципе все работает так как ожидалось. Проблемы начинаются при тестах с картами DESFire.
Принцип APDU команд для DESFire в DUALi хотя бы можно понять. Есть два байта для {CLA, INS}, они не меняются и по сути говорят о том, что команда предназначена для карт типа DESFire. Параметры 1 и 2 также не меняются. В передаваемых данных уже содержится часть нативной команды DESFire, а именно байты {INS, Data}. Около недели мы не могли получить ожидаемые ответы на простые команды, например, команда "выбора приложения". В самом начале кода, мы оставили исполнение APDU команды GetCardStatus, которая не была формата команд для DESFire. Однако она работала и выдавала UID карты. Как оказалось, после исполнения GetCardStatus команды DESFire переставали работать. Данное упущение было определено нашими силами, после недельного диалога с поставщиком, который ни к чему не привёл.
После месяца стабильной работы нашей программы, мы пришли к необходимости переписывания программы на C#. Основная причина была в настройке CI. Программа на C++ компилировалась посредством Microsoft Visual Studio. Все наши сервера работают на ОС Linux, так что запуск докера с Windows и необходимыми Visual Studio ToolKit не представлялось возможным. Конечно можно было поднять виртуалку с Windows и все-таки настроить все для C++, но не очень хотелось. После повторного запроса примера кода на C# у производителя, нам предоставили пример. Можно было и самим написать, основываясь на определениях методов в примере интерфейса на C++, но оказалось не все функции были описаны. Пример очень помог и в итоге мы переписали программу на C# и настроили CI.
2.3. Печать
На первый взгляд кажется, что печать не должна вызывать проблем, т. к. в первую очередь мы используем принтеры печати. Если кодировка зависит от считывателей разных компаний, которые являются комплектующей частью, то печать это основа принтера и сама компания производитель отвечает за неё.
На первом этапе нас интересовала цветная печать. На входе мы имеем пустую белую карту, на выходе ожидаем карту с напечатанным дизайном, с двух сторон.
2.3.1. Печать на Evolis Primacy
Команды печати представляют собой JSON объекты, передаваемые как HTTP запросы. Эти запросы принимаются Evolis Services Provider, который должен быть уже запущен на подключённом к принтеру ПК. Печать одной стороны происходит в 8 команд:
- Объявляем о начале последовательности команд
- Инициализируем печать
- Определяем параметры печати: тип ленты, двусторонняя или односторонняя, и т. д.
- Загрузка цветной картинки
- Загрузка чёрной составляющей картинки
- Загрузка защитной поверхности
- Запуск печати
- Объявление конца печати
Первое время конфуз возникал из-за команд 4-6, т. к. не совсем понятно нужны ли они все и в каком формате передавать картинку для печати. Также возникали проблемы с двусторонней печатью. В итоге с помощью техподдержки и последней версии SDK, проблемы с запуском всех команд были решены. Однако встал вопрос качества печати.
Качество печати зависит от нескольких факторов:
- Поверхность карты
Поверхность карты должна быть ровной и чистой. - Чистота принтера
Требуется соблюдать все правила чистки принтера.
Первое время мы получали карты с неровным цветом на фоне и с белым пятном в одном и том же месте. Пару недель мы потратили на поиск решения проблемы качества печати, пока не получили объяснение от техподдержки. Карты с чипами априори являются не самыми лучшими для выбранных принтеров. В области расположения чипа, поверхность карты неровная. По этой причине качество печати в этом месте особенно низкое. Также качество печати разнится в зависимости от выбранного дизайна. Если в дизайне много однородного цвета, например синий фон, то синий цвет не будет одинаковым во всех местах, рисунок 3.
![drawing](https://habrastorage.org/webt/pa/4_/i8/pa4_i8xhdbhicczzxejgvzayzne.jpeg)
Рисунок 3 — Печать однородного фона
Тестовая печать для рисунка 3 была проведена имеющимся готовым софтом для принтеров от производителя.
В итоге было решено использовать принтеры для печати исключительно индивидуальной информации о карточке, т. е. номер карты и QR-код. Для этого не требуется цветная лента, по дизайну информация о номере карты и QR-код чёрного цвета. В результате использования монохромной ленты, из последовательности команд для печати, команды 4 и 6 выпадают.
Во время печати, Evolis принтер, посредством программы Evolis Print Center, помогает получать сообщения об ошибках, уведомления о необходимости чистки, сообщения о нехватке карт в подающем лотке или превышающее количество карт в выходном лотке. Данное общение помогает определять состояние принтера и является понятным для обычных пользователей.
2.3.2. Печать на Smart-51
В первую очередь мы проверили, с помощью предоставленного софта SmartID, цветную печать всего дизайна карты. Увидели те же проблемы в качестве, что и с печатью на Evolis. Однако от техподдержки мы сразу получили два совета:
- Изменить дизайн так, чтоб печать не производилась на месте расположения чипа.
- Печатать цветной дизайн в типографии, а принтером только индивидуальную информацию.
По сути мы сразу получили совет на то же решение, к которому пришли спустя недели. Удивительно просто получилось запрограммировать печать на Smart-51. Алгоритм печати следующий:
- Поместить карту в слот печати
- Вызвать функцию печати текста, номера карты.
- Инициализировать печать
- Провести печать
- Вызвать функцию печати штрихкода, указав тип QR-код
- Инициализировать печать
- Провести печать
- Обозначить завершение печати
На каждую необходимую функцию, есть небольшое описание в User Manuals принтера. В описании функции печати штрихкода сказано, что её вызов обнуляет вызовы функций печати других объектов, поэтому приходится инициировать и запускать печать два раза.
2.3.3. Общие проблемы с печатью
Помимо проблемы качества печати, у обоих принтеров есть проблема со стиранием печати. По скольку нам приходится работать с картами, на которых уже напечатан общий дизайн, то и на первозданную гладкость карт рассчитывать не приходится. На матовой поверхности напечатанный номер можно легко стереть обычной стирательной резинкой. Было решено печатать глянцевые поверхности на первое время. Параллельно мы пробуем освоить модули ламинирования, которые поставляются самими производителями.
Вместимость лотка подачи карт для Evolis Primacy принтеров заявлена как 100 карт, при размере 0,76 мм. Однако в реальности мы смогли уместить, только 86 карт. В принтер Smart-51 может влезть больше 100 карт, но только если не закрывать крышку лотка для подачи карт. Хотя различия небольшие, но все же несоответствие документации есть.
3. Результаты
Ниже представлены результаты по времени работы одного цикла программы. Качество печати индивидуальной информации для нас недостаточно приемлемое. При длительном стирании резинкой номер все же стирается. Ламинирование карты занимает около 17 секунд. Это слишком большой проигрыш в скорости для нас.
Принтер | Время кодировки, с | Время печати, с | Итого |
---|---|---|---|
Evolis Primacy | ≈ 10 | ≈ 10 | ≈ 20 |
Smart-51 | ≈ 17 | ≈ 6 | ≈ 23 |
![drawing](https://habrastorage.org/webt/aa/tu/r2/aatur26peetmxaj2ynj4jxwxshm.jpeg)
а)
![drawing](https://habrastorage.org/webt/ll/y1/ed/lly1edhu6n42rdbybxn4-gwvniu.jpeg)
б)
Рисунок 4 — Результат печати: а — хорошего качества, б — плохого качества
4. Заключение
Это был действительно интересный новый опыт работы с NFC картами и карт-принтерами. Абсолютного победителя у нас не оказалось, т.к. везде были свои плюсы и минусы. По скорости Smart-51 сильно уступает Evolis Primacy. Однако у принтера Evolis часто проявляются проблемы с застреванием карты внутри, плюс он требует частого ухода. Smart-51 хорошо себя показал в плане надёжности и стабильности всего цикла кодировки и печати. Также время установки всего окружения для Smart-51 значительно меньше в сравнении с Evolis. Выбор принтера зависит от того сильно ли важна скорость и насколько аккуратен будет персонал, работающий с принтером. С Evolis Primacy приходится часто взаимодействовать, чистить и исправлять застревание карты. Поэтому персонал должен быть предельно аккуратен. Со Smart-51 в этом плане легче. Карты не застревают, открывать крышку принтера нужно только при смене ленты и чистки.
На данный момент мы используем оба принтера, т.к. заинтересованы в выпуске большого количества карт в кратчайшие сроки. Однако в будущем надеемся либо улучшить работу с принтерами и остановиться на одном типе, либо продолжим поиски более подходящего принтера под наши запросы.
Список литературы
- https://ironlogic.ru/il.nsf/htm/ru_z2usb
- https://www.nxp.com/products/rfid-nfc/mifare-hf/mifare-desfire/mifare-desfire-ev2:MIFARE_DESFIRE_EV2_2K_8K
- https://www.nxp.com/docs/en/data-sheet/MF3DX2_MF3DHX2_SDS.pdf
- https://www.nxp.com/docs/en/data-sheet/MF1S50YYX_V1.pdf
- https://www.nxp.com/docs/en/data-sheet/MF3DX2_MF3DHX2_SDS.pdf
- https://www.eftlab.com/knowledge-base/complete-list-of-apdu-responses/
- Advanced Card Systems Guide http://downloads.acs.com.hk/drivers/en/API-ACR122U-2.02.pdf
- Mifare Desfire communication example https://ridrix.wordpress.com/2009/09/19/mifare-desfire-communication-example/
- Mifare DESFire Data Sheet http://neteril.org/files/M075031_desfire.pdf
- Проект на GitHub для DESFire https://github.com/EsupPortail/esup-nfc-tag-server/blob/master/src/main/java/nfcjlib/core/DESFireEV1.java