Mobius 2026 Autumn

圣彼得堡 + 线上

深入底层 10月22日 · 俄语

Android 中的
NFC 内部机制:

从 APDU
到 NCI 和 RF

我把一次失败的护照读取从 Kotlin 经过 APDU 和 NCI 一路追到射频链路,再讲怎样安全地恢复。

主办方:JUG Ru Group
mobiusconf.com 上的演讲页面 (在新标签页中打开)

从这里开始

  1. 03 文字读完了,照片没读完 Вступление
  2. 12 APDU:SELECT、READ BINARY 和状态字 APDU
  3. 21 NCI credits:管理 NFCC 缓冲区 NCI/NFCC
  4. 24 TagLostException:最后一次交互的结果未知 ISO-DEP/RF
  5. 32 下次故障怎么排查 Выводы

章节

  1. 1–3 第 1–3 张幻灯片 Вступление 标题页、自我介绍和这次故障
  2. 4–6 第 4–6 张幻灯片 Камера / OCR NFC 交互有哪些参与方;NFC 之前的 OCR 和 MRZ
  3. 7–8 第 7–8 张幻灯片 MRZ 我们场景中的主要文件
  4. 9–10 第 9–10 张幻灯片 PACE/BAC 为什么需要 PACE 和 BAC
  5. 11–12 第 11–12 张幻灯片 APDU SELECT、READ BINARY 和状态字
  6. 13–17 第 13–17 张幻灯片 Android Reader Mode、IsoDep、discovery、transceive()
  7. 18–21 第 18–21 张幻灯片 NCI/NFCC 控制包和数据包;NCI credits
  8. 22–24 第 22–24 张幻灯片 ISO-DEP/RF 三种互相独立的拆分;TagLostException
  9. 25–29 第 25–29 张幻灯片 Диагностика SDK 日志对照 NCI trace;RF A/B 测试
  10. 30–32 第 30–32 张幻灯片 Выводы 我们知道什么,接下来做什么
  11. 33 第 33 张幻灯片 Вопросы 问答

幻灯片

  1. 第 1 张幻灯片NFC в Android: как команда проходит от Kotlin до RF

    第 1 张幻灯片 · Вступление

    NFC в Android: как команда проходит от Kotlin до RF

  2. 第 2 张幻灯片Коротко обо мне. Владислав Томилов Lead Software Engineer, Mobile 4wl2d tomilov.tech

    第 2 张幻灯片 · Вступление

    Коротко обо мне

  3. 第 3 张幻灯片Текст прочитан, фото не дочитано. Строка поиска: TagLostException. Телефон с песочными часами над документом.

    第 3 张幻灯片 · Вступление

    Текст прочитан, фото не дочитано

  4. 第 4 张幻灯片Раздел «Камера / OCR»

    第 4 张幻灯片 · Камера / OCR

    Раздел «Камера / OCR»

  5. 第 5 张幻灯片Кто участвует в NFC-обмене. OCR и MRZ Binder/API NCI ISO-DEP/RF ТЕЛЕФОН Приложение Чип документа Android NFC- eMRTD / IsoDep. контроллер passive tag transceive NFC stack reader tag APDU NCI ISO-DEP телефон: создаёт чип: получает прикладная обмен Android обмен поле и начинает питание от поля и команда или host с NFC- контроллера с обмен отвечает ответ контроллером чипом по RF

    第 5 张幻灯片 · Камера / OCR

    Кто участвует в NFC-обмене

  6. 第 6 张幻灯片OCR и MRZ: что происходит до NFC. Кто участвует OCR и MRZ: что происходит до NFC Номер документа Кадр с камеры L 8 9 8 9 0 2 C 3 OCR: распознать печатный текст Ошибка в имени не ломает MRZ: номер, даты, контрольные цифры L 8 9 8 9 О 2 C 3 Проверка контрольных цифр Ошибка здесь ломает доступ MRZInfo для BAC / PACE-MRZ

    第 6 张幻灯片 · Камера / OCR

    OCR и MRZ: что происходит до NFC

  7. 第 7 张幻灯片Раздел «MRZ»

    第 7 张幻灯片 · MRZ

    Раздел «MRZ»

  8. 第 8 张幻灯片Основные файлы в нашем сценарии. Master File Корень файловой структуры EF.CardAccess Параметры доступных вариантов PACE LDS1 application Выбирается по AID фрагмент структуры EF.DG1 Полное представление MRZ EF.DG2 Биометрическая запись лица EF.SOD Хеши Data Groups и подпись EF DG LDS отдельный файл Data Group стандартная структура данных и файлов

    第 8 张幻灯片 · MRZ

    Основные файлы в нашем сценарии

  9. 第 9 张幻灯片Раздел «PACE/BAC»

    第 9 张幻灯片 · PACE/BAC

    Раздел «PACE/BAC»

  10. 第 10 张幻灯片Зачем нужны PACE и BAC. BAC PACE Полное имя Basic Access Control Password Authenticated Connection Establishment Вход Данные MRZ MRZ, иногда CAN Механизм Старый симметричный протокол Password-authenticated key agreement Результат Session keys и secure Session keys и secure messaging messaging CAN MAC SSC короткий номер, напечатанный на код, защищающий команду или Send Sequence Counter некоторых документах ответ от изменения синхронный счётчик secure messaging

    第 10 张幻灯片 · PACE/BAC

    Зачем нужны PACE и BAC

  11. 第 11 张幻灯片Раздел «APDU»

    第 11 张幻灯片 · APDU

    Раздел «APDU»

  12. 第 12 张幻灯片APDU: SELECT, READ BINARY и status word. Command APDU CLA INS P1 P2 Lc data Le 00 A4 04 0C 07 A0 00 00 02 47 10 01 — SELECT 7 байт AID приложения Response APDU [data] SW1 SW2 — 90 00 успех CLA INS P1/P2 Lc Le SELECT READ BINARY class instruction параметры длина данных максимальная ожидаемая выбрать приложение или (offset, Le) byte команды команды длина response data файл прочитать блок данных

    第 12 张幻灯片 · APDU

    APDU: SELECT, READ BINARY и status word

  13. 第 13 张幻灯片Раздел «Android»

    第 13 张幻灯片 · Android

    Раздел «Android»

  14. 第 14 张幻灯片Reader Mode. IsoDep Discovery transceive() nfcAdapter.enableReaderMode( activity, { tag -> scope.launch(ioDispatcher) { readDocument(tag) } }, FLAG_READER_NFC_A or FLAG_READER_NFC_B or FLAG_READER_SKIP_NDEF_CHECK, null )

    第 14 张幻灯片 · Android

    Reader Mode

  15. 第 15 张幻灯片IsoDep. Reader Mode IsoDep Discovery transceive() val isoDep = IsoDep.get(tag) IsoDep.get(tag) ?: return ?.use { isoDep -> isoDep.use { isoDep.connect() it.connect() или isoDep.timeout = 5_000 it.timeout = 5_000 readDocument(isoDep) readDocument(it) } } один владелец одно место одна очередь APDU сессии закрывает IsoDep

    第 15 张幻灯片 · Android

    IsoDep

  16. 第 16 张幻灯片Discovery и activation до ReaderCallback. Reader Mode IsoDep Discovery и activation до ReaderCallback transceive() Reader Mode включён Discovery: NFCC опрашивает NFC-A / NFC-B Selection: host и NFCC выбирают target Activation: NFCC настраивает ISO-DEP и RF connection ReaderCallback(tag) Дальше работает ваш код IsoDep.connect() всё, что выше, происходит до callback. Из кода на это влияют только флаги Reader Mode Первый APDU

    第 16 张幻灯片 · Android

    Discovery и activation до ReaderCallback

  17. 第 17 张幻灯片Что делает transceive() внутри Android. Reader Mode IsoDep Discovery Что делает transceive() внутри Android Упрощённая схема по AOSP Команда вниз Ответ вверх App / IsoDep App Binder: INfcTag, NfcService.TagService Blocked transceive() resumes JNI Response buffer Native NFC stack HAL / native completion NFC HAL Vendor transport NFCC

    第 17 张幻灯片 · Android

    Что делает transceive() внутри Android

  18. 第 18 张幻灯片Раздел «NCI/NFCC»

    第 18 张幻灯片 · NCI/NFCC

    Раздел «NCI/NFCC»

  19. 第 19 张幻灯片NCI: control packets и data packets. NCI credits CONTROL packet MT PBF GID RFU OID Length payload byte 0 byte 0 byte 0 byte 1 byte 1 byte 2 payload DATA packet, NCI 2.x MT=DATA PBF ConnID RFU CR Length payload CR: 2 бита для возврата credits в Data Packet. В NCI 1.x на их месте RFU MT PBF RFU GID / OID ConnID Length тип сообщения есть ли зарезервировано группа и logical длина payload продолжение операция connection

    第 19 张幻灯片 · NCI/NFCC

    NCI: control packets и data packets

  20. 第 20 张幻灯片NCI: CMD, RSP, NTF и DATA. NCI: control packets и data packets NCI credits MT host NFCC CMD RF_DISCOVER_CMD RSP RF_DISCOVER_RSP NTF RF_INTF_ACTIVATED_NTF приходит сам, без запроса после ISO-DEP activation DATA NCI Data Messages с защищёнными APDU

    第 20 张幻灯片 · NCI/NFCC

    NCI: CMD, RSP, NTF и DATA

  21. 第 21 张幻灯片NCI credits: управление буферами NFCC. NCI packets NCI credits: управление буферами NFCC для ConnID = 0 NFCC объявил 2 credits host NFCC credits Data Packet A (2) Data Packet B (1) Data Packet C (0) ждёт в очереди CORE_CONN_CREDITS_NTF(+1) (1) Data Packet C (0) 1 credit = право отправить 1 NCI Data Packet на конкретном ConnID. Это не байты, не время, не retry и не качество RF

    第 21 张幻灯片 · NCI/NFCC

    NCI credits: управление буферами NFCC

  22. 第 22 张幻灯片Раздел «ISO-DEP/RF»

    第 22 张幻灯片 · ISO-DEP/RF

    Раздел «ISO-DEP/RF»

  23. 第 23 张幻灯片Три независимых разбиения. TagLostException 1. Файл и APDU READ BINARY(offset, Le) READ BINARY(offset, Le) host и файл размер блока выбирает SDK 2. NCI PBF=1 PBF=1 PBF=1 PBF=0 host и NFCC NCI Data Message делится на Data Packets, отправку ограничивают credits 3. ISO-DEP NFCC и chip I-блоки, chaining делают stack и NFCC границы разбиений не обязаны совпадать FSD FSC getMaxTransceiveLength() max RF frame у reader max RF frame у chip предел команды Android API

    第 23 张幻灯片 · ISO-DEP/RF

    Три независимых разбиения

  24. 第 24 张幻灯片TagLostException: исход последнего обмена неизвестен. Три разбиения TagLostException: исход последнего обмена неизвестен SSC phone один из возможных chip SSC сценариев n n protected READ, MAC(SSC=n+1) n+1 protected response, MAC(SSC=n+2) ответ потерян счётчики разошлись n+2 неизвестно, обработал ли chip команду нельзя повторять те же protected bytes новая новый PACE / новый secure продолжить с activation BAC messaging последнего блока

    第 24 张幻灯片 · ISO-DEP/RF

    TagLostException: исход последнего обмена неизвестен

  25. 第 25 张幻灯片Раздел «Диагностика»

    第 25 张幻灯片 · Диагностика

    Раздел «Диагностика»

  26. 第 26 张幻灯片Что известно в нашем кейсе. SDK log и NCI trace RF A/B-тест MRZ проверена Где обрыв? ReaderCallback приложение PACE Android / vendor DG1 NFCC DG2, первые блоки RF TagLostException

    第 26 张幻灯片 · Диагностика

    Что известно в нашем кейсе

  27. 第 27 张幻灯片Сопоставляем SDK log и NCI trace. Что известно Сопоставляем SDK log и NCI trace RF A/B-тест SDK LOG (пример) 0000 tag_discovered tech=IsoDep/NfcA 0618 pace ok 1042 dg1 ok size=93 1886 dg2_read offset=0x1C00 le=224 tx_len=... rx_len=0 NCI TRACE (пример) Вопрос залу Какое событие подтвердит, что запрос вышел ниже приложения?

    第 27 张幻灯片 · Диагностика

    Сопоставляем SDK log и NCI trace

  28. 第 28 张幻灯片SDK log и NCI trace: что логировать. Что известно Сопоставляем SDK log и NCI trace RF A/B-тест SDK LOG (пример) 0000 tag_discovered tech=IsoDep/NfcA 0618 pace ok 1042 dg1 ok size=93 1886 dg2_read offset=0x1C00 le=224 tx_len=... rx_len=0 NCI TRACE (пример) 1887 TX DATA conn=0 pbf=0 len=... 6888 RX CORE_INTERFACE_ERROR_NTF status=0xB2 6889 RX RF_DEACTIVATE_NTF логировать не логировать session=... monotonic=1886 mrz= step=dg2_read offset=0x1C00 uid= le=224 tx/rx=.../0 photo= duration=... result=TagLost apdu= model/build=... cryptogram=

    第 28 张幻灯片 · Диагностика

    SDK log и NCI trace: что логировать

  29. 第 29 张幻灯片RF A/B-тест и различия устройств. Что известно SDK log и NCI trace RF A/B-тест и различия устройств общая часть NfcService native stack HAL Android зависит от NFCC корпус / vendor impl. transport RF config антенна устройства firmware чехол Телефон / build Чехол Положение Le Успех Последнее событие проблемный есть зона антенны 224 __ / 10 __ проблемный снят зона антенны 224 __ / 10 __ проблемный снят центр корпуса 224 __ / 10 __ контрольный снят зона антенны 224 __ / 10 __

    第 29 张幻灯片 · Диагностика

    RF A/B-тест и различия устройств

  30. 第 30 张幻灯片Раздел «Выводы»

    第 30 张幻灯片 · Выводы

    Раздел «Выводы»

  31. 第 31 张幻灯片Вывод по кейсу: что известно и что делать. Алгоритм разбора что знаем меняем не утверждаем PACE, DG1, часть DG2 MRZ проверяем до NFC виноват OCR один владелец, одна очередь Data Packet ушёл к NFCC любой retry безопасен APDU новая PACE/BAC-сессия после RF timeout и deactivation timeout улучшает RF потери ждём A/B: телефон и зона антенны, снять чехол антенна неисправна положение ждём A/B: размер блока профиль блока по тестам причина в размере DG2

    第 31 张幻灯片 · Выводы

    Вывод по кейсу: что известно и что делать

  32. 第 32 张幻灯片Алгоритм разбора следующего сбоя. Вывод по кейсу Алгоритм разбора следующего сбоя Контрольные цифры MRZ сошлись? Пришёл активированный Tag? Какой шаг PACE/BAC или чтения завершился последним? Ушёл ли Data Packet к NFCC? Ждал ли он credit? Что пришло первым: response, timeout или deactivation? Правка устраняет причину или снижает вероятность?

    第 32 张幻灯片 · Выводы

    Алгоритм разбора следующего сбоя

  33. 第 33 张幻灯片Спасибо за внимание. Время вопросов и ответов 4wl2d tomilov.tech

    第 33 张幻灯片 · Вопросы

    Спасибо за внимание