Android NFC связь с Mifare DESFire EV1
Использование Nexus 4 и новейшего Android API уровня 18 для взаимодействия с тегом AES Mifare DESFire EV1 доставляет мне головную боль. В соответствии с собственным протоколом NXP для записи и чтения тегов этого типа необходимо выполнить следующие шаги:
- Выберите приложение
- проверять подлинность
- Написать или прочитать
Для этого я использую класс IsoDep для Android, который обеспечивает доступ к свойствам ISO 14443-4 и операциям ввода-вывода. Очень странная вещь в том, что когда я отправляю собственную команду select application, я получаю неожиданный ответ. Представь, что у меня есть ПОМОЩЬ F4013D
поэтому я отправляю:
-> 5AF4013D
<- 6E00
Все возможные ответы должны быть длиной в один байт (успех 0x00
или error_code) и никогда два или более. Таким образом 0x6E
до успеха ответ абсолютно неожиданный. Это происходит не всегда, и когда это не так и работает нормально, процессы выбора приложения и аутентификации работают нормально. Однако после аутентификации команда записи не имеет правильного поведения, все команды записи заканчиваются 0xAF
от PICC вместо успеха 0x00
, Похоже, что PICC ожидает каких-то дополнительных данных, когда это не должно (я посылаю полезную нагрузку правильной длины). Если я отправлю любую другую команду, я получу 0xCA
(Команда прервана) код ошибки.
-> 5AF4013D
<- 00 /*Success*/
-> AA01
<- AFA8394ED57A5E83106B4EE72FD2BB0CC4
-> AF148F525E1DDE0AD6AB60B4B615552475C91F2E8D89B8523E4465113DD5BD19C6
<- 0066D255C93F2F492AFE3715C88964F1BD /*Authentication success*/
-> 3D02000000030000222222 /*Write 3 bytes to file nº2*/
<- AF /*Unexpected, 0x00 was expected*/
Как обычно, если я отправляю команды такого типа с персональным ридером (не Android NFC), он всегда работает нормально. Кажется, что-то в Android NFC API идет странно, когда это должен быть просто транспортер необработанных данных, который никогда не интерпретирует и не модифицирует данные.
Я также попытался с APDU структуры ISO 7816-4 с тем же результатом. Как любопытство, с Galaxy Nexus не бывает странного ответа выбранного приложения, но да команда записи одна всегда.
2 ответа
(1) Для первой части, касающейся кода состояния 6E00:
6E 00
не странный байт 0x6E
+ код статуса успеха 0x00
". Вместо этого это ответное слово состояния APDU. 6E 00
("Класс не поддерживается"). Это указывает на то, что ранее была связь с картой с использованием доступа на основе APDU (например, сам Android пытался считывать карту как тег типа 4 и впоследствии не сбрасывал соединение). Таким образом, карта будет ожидать, что вся дальнейшая связь будет в APDU ISO 7816-4. В этом случае (т.е. если вы получаете код состояния ISO 7816-4, например, 6E 00
), вы могли бы продолжать использовать обернутые команды DESFire APDU, просто оборачивая ваши собственные команды.
РЕДАКТИРОВАТЬ: На самом деле, это несколько ожидаемое поведение на устройстве NFC. Идея заключается в том, что устройство NFC будет автоматически сканировать обнаруженные теги на наличие сообщений NDEF. В случае карты DESFire устройство NFC обнаружит карту в качестве потенциальной метки типа 4. Таким образом, устройство NFC будет отправлять APDU ISO 7816-4 так же, как и на любой другой тег типа 4. Следовательно, если устройство NFC не сбрасывает связь с тегом перед передачей обнаруженного тега в приложение, приложение может взаимодействовать только с использованием APDU ISO 7816-4. Обратите внимание, однако, что я бы посчитал ошибкой то, что это происходит только для некоторых активаций на одном устройстве. На мой взгляд, поведение на одной конкретной модели устройства должно быть согласованным.
РЕДАКТИРОВАТЬ: Хотя я не считаю это поведение ошибкой, на самом деле это вызвано известной ошибкой ( # 58773) в стеке NFC Android для устройств с контроллером Broadcom NFC. На уязвимых устройствах автоматическая проверка присутствия отправляет APDU ISO 7816-4 через определенные промежутки времени, в результате чего карты DESFire переключаются в режим APDU ISO 7816-4.
(2) Для второй части, касающейся (неожиданного) кода ответа 0xAF:
Может ли быть так, что настройки связи вашего файла настроены на "простую связь, защищенную MACing" или "полностью зашифрованную связь"? В этом случае простой отправки трех байтов данных будет недостаточно. Вместо этого вам нужно будет отправить либо простые данные плюс MAC, либо дополненные, CRCed и зашифрованные данные. Следовательно 0xAF
указывая, что карта ожидает дальнейших данных.
РЕДАКТИРОВАТЬ: Итак, чтобы суммировать комментарии ниже. После отправки следующих байтов (по одному байту за каждый полученный 0xAF
код состояния: AF FF
) оказалось, что карта ожидала ровно еще 8 байт. 8 байтов - это точно размер CMAC для аутентификации AES. Таким образом, параметры связи были установлены на "обычную связь, защищенную MACing".
Вы можете найти хорошую библиотеку с несколькими примерами здесь: https://github.com/grundid/nfctools
Здесь также есть еще один пример с некоторыми примерами: https://code.google.com/p/ismb-npp-java/
Я надеюсь, что эта помощь для вашей цели!