Многие устройства на платформе Android, предлагающие функцию NFC, уже поддерживают эмуляцию карт NFC. В большинстве случаев карту эмулирует отдельный чип в устройстве, называемый элементом безопасности . Многие SIM-карты, предоставляемые операторами беспроводной связи, также содержат элемент безопасности.
В Android 4.4 и более поздних версиях предусмотрен дополнительный метод эмуляции карты, не требующий использования элемента безопасности, который называется эмуляцией карты на основе хоста . Это позволяет любому приложению Android эмулировать карту и напрямую обращаться к считывателю NFC. В этом разделе описывается, как эмуляция карты на основе хоста (HCE) работает на Android и как можно разработать приложение, эмулирующее карту NFC, используя этот метод.
Эмуляция карты с элементом безопасности
Когда эмуляция карты NFC обеспечивается с использованием защищенного элемента, эмулируемая карта передается в защищенный элемент на устройстве через приложение Android. Затем, когда пользователь подносит устройство к терминалу NFC, контроллер NFC в устройстве направляет все данные от считывателя непосредственно к защищенному элементу. Рисунок 1 иллюстрирует эту концепцию:
Элемент безопасности сам осуществляет связь с терминалом NFC, и в транзакции не участвует никакое приложение Android. После завершения транзакции приложение Android может запросить статус транзакции непосредственно у защищенного элемента и уведомить пользователя.
Эмуляция карты на базе хоста
Когда карта NFC эмулируется с использованием эмуляции карты на базе хоста, данные направляются непосредственно в центральный процессор, а не на безопасный элемент. На рис. 2 показано, как работает эмуляция карты на базе хоста:
Поддерживаемые карты и протоколы NFC
Стандарты NFC поддерживают множество различных протоколов, и существуют разные типы карт, которые можно эмулировать.
Android 4.4 и более поздние версии поддерживают несколько протоколов, которые сегодня распространены на рынке. Многие существующие бесконтактные карты уже основаны на этих протоколах, например карты бесконтактной оплаты. Эти протоколы также поддерживаются многими считывателями NFC, представленными сегодня на рынке, включая устройства Android NFC, сами функционирующие как считыватели (см. класс IsoDep
). Это позволяет вам создать и развернуть комплексное решение NFC на базе HCE, используя только устройства на базе Android.
В частности, Android 4.4 и более поздние версии поддерживают эмуляцию карт, основанных на спецификации NFC-Forum ISO-DEP (на основе ISO/IEC 14443-4) и обрабатывают блоки данных протокола приложения (APDU), как определено в ISO/IEC 7816-4. спецификация. Android требует эмуляции ISO-DEP только поверх технологии Nfc-A (ISO/IEC 14443-3 Type A). Поддержка технологии Nfc-B (ISO/IEC 14443-4, тип B) не является обязательной. Рисунок 3 иллюстрирует слои всех этих спецификаций.
услуги HCE
Архитектура HCE в Android основана на компонентах Service
Android (известных как службы HCE ). Одним из ключевых преимуществ службы является то, что она может работать в фоновом режиме без какого-либо пользовательского интерфейса. Это естественно подходит для многих приложений HCE, таких как карты лояльности или транспортные карты, для использования которых пользователю не нужно запускать приложение. Вместо этого прикосновение устройства к считывателю NFC запускает нужную службу, если она еще не запущена, и выполняет транзакцию в фоновом режиме. Конечно, вы можете запускать дополнительный пользовательский интерфейс (например, уведомления пользователей) из своего сервиса, когда это необходимо.
Выбор услуги
Когда пользователь подносит устройство к считывателю NFC, системе Android необходимо знать, с какой службой HCE считыватель NFC хочет связаться. Спецификация ISO/IEC 7816-4 определяет способ выбора приложений, основанный на идентификаторе приложения (AID). AID состоит из 16 байт. Если вы эмулируете карты для существующей инфраструктуры считывателей NFC, идентификаторы AID, которые ищут эти считыватели, обычно хорошо известны и публично зарегистрированы (например, идентификаторы AID платежных сетей, таких как Visa и MasterCard).
Если вы хотите развернуть новую инфраструктуру чтения для своего приложения, вам необходимо зарегистрировать свои собственные AID. Процедура регистрации AID определена в спецификации ISO/IEC 7816-5. Мы рекомендуем зарегистрировать AID согласно 7816-5, если вы развертываете приложение HCE для Android, поскольку это позволяет избежать конфликтов с другими приложениями.
группы помощи
В некоторых случаях службе HCE может потребоваться зарегистрировать несколько AID и установить их в качестве обработчика по умолчанию для всех AID, чтобы реализовать определенное приложение. Некоторые AID в группе, переходящие в другую службу, не поддерживаются.
Список AID, которые хранятся вместе, называется группой AID. Для всех AID в группе AID Android гарантирует одно из следующих условий:
- Все AID в группе направляются в эту службу HCE.
- Никакие AID в группе не перенаправляются в эту службу HCE (например, потому, что пользователь предпочел другую службу, которая также запросила один или несколько AID в вашей группе).
Другими словами, не существует промежуточного состояния, в котором некоторые AID в группе могут быть перенаправлены в одну службу HCE, а некоторые — в другую.
Группы и категории помощи
Вы можете связать каждую группу AID с категорией. Это позволяет Android группировать службы HCE по категориям, а это, в свою очередь, позволяет пользователю устанавливать значения по умолчанию на уровне категории, а не на уровне AID. Избегайте упоминания AID в любых частях вашего приложения, ориентированных на пользователя, поскольку для обычного пользователя они ничего не значат.
Android 4.4 и выше поддерживает две категории:
-
CATEGORY_PAYMENT
(охватывает стандартные платежные приложения) -
CATEGORY_OTHER
(для всех остальных приложений HCE)
Внедрить сервис HCE
Чтобы эмулировать карту NFC с помощью эмуляции карты на основе хоста, вам необходимо создать компонент Service
, который обрабатывает транзакции NFC.
Проверьте поддержку HCE
Ваше приложение может проверить, поддерживает ли устройство HCE, проверив функцию FEATURE_NFC_HOST_CARD_EMULATION
. Используйте тег <uses-feature>
в манифесте вашего приложения, чтобы объявить, что ваше приложение использует функцию HCE, а также указать, требуется ли она для работы приложения или нет.
Реализация услуги
Android 4.4 и более поздних версий предоставляет удобный класс Service
, который можно использовать в качестве основы для реализации службы HCE: класс HostApduService
.
Первым шагом является расширение HostApduService
, как показано в следующем примере кода:
Котлин
class MyHostApduService : HostApduService() { override fun processCommandApdu(commandApdu: ByteArray, extras: Bundle?): ByteArray { ... } override fun onDeactivated(reason: Int) { ... } }
Ява
public class MyHostApduService extends HostApduService { @Override public byte[] processCommandApdu(byte[] apdu, Bundle extras) { ... } @Override public void onDeactivated(int reason) { ... } }
HostApduService
объявляет два абстрактных метода, которые необходимо переопределить и реализовать. Один из них, processCommandApdu()
, вызывается всякий раз, когда устройство чтения NFC отправляет в вашу службу блок данных протокола приложения (APDU). APDU определены в спецификации ISO/IEC 7816-4. APDU — это пакеты уровня приложения, которыми обмениваются устройство чтения NFC и ваша служба HCE. Этот протокол уровня приложения является полудуплексным: считыватель NFC отправляет вам командный APDU и ждет, пока вы отправите ответный APDU в ответ.
Как упоминалось ранее, Android использует AID, чтобы определить, с какой службой HCE хочет связаться читатель. Обычно первый APDU, который считыватель NFC отправляет на ваше устройство, — это APDU SELECT AID
; этот APDU содержит AID, с которым хочет связаться читатель. Android извлекает этот AID из APDU, преобразует его в службу HCE, а затем пересылает этот APDU в разрешенную службу.
Вы можете отправить ответный APDU, вернув байты ответного APDU изprocessCommandApdu processCommandApdu()
. Обратите внимание, что этот метод вызывается в основном потоке вашего приложения, который не следует блокировать. Если вы не можете немедленно вычислить и вернуть ответный APDU, верните ноль. Затем вы можете выполнить необходимую работу в другом потоке и использовать метод sendResponseApdu()
определенный в классе HostApduService
для отправки ответа, когда вы закончите.
Android продолжает пересылать новые APDU от устройства чтения в вашу службу до тех пор, пока не произойдет одно из следующих событий:
- Считыватель NFC отправляет еще один APDU
SELECT AID
, который ОС преобразует в другую службу. - Соединение NFC между устройством чтения NFC и вашим устройством нарушено.
В обоих этих случаях реализация onDeactivated()
вашего класса вызывается с аргументом, указывающим, какое из двух событий произошло.
Если вы работаете с существующей инфраструктурой считывателей, вам необходимо реализовать существующий протокол уровня приложения, который ожидают считыватели в вашем сервисе HCE.
Если вы развертываете новую инфраструктуру чтения, которую вы также контролируете, вы можете определить свой собственный протокол и последовательность APDU. Постарайтесь ограничить количество APDU и размер данных для обмена: это гарантирует, что вашим пользователям придется держать свое устройство над считывателем NFC только в течение короткого периода времени. Разумная верхняя граница составляет около 1 КБ данных, обмен которыми обычно осуществляется в течение 300 мс.
Декларация сервисного манифеста и регистрация AID
Вы должны объявить свою службу в манифесте, как обычно, но вы также должны добавить некоторые дополнительные элементы в объявление службы:
Чтобы сообщить платформе, что это служба HCE, реализующая интерфейс
HostApduService
, добавьте фильтр намерений для действияSERVICE_INTERFACE
в объявление службы.Чтобы сообщить платформе, какие группы AID запрашиваются этой службой, включите тег
SERVICE_META_DATA
<meta-data>
в объявление службы, указывающий на XML-ресурс с дополнительной информацией о службе HCE.Установите для атрибута
android:exported
значениеtrue
и запросите разрешениеandroid.permission.BIND_NFC_SERVICE
в объявлении службы. Первый гарантирует, что к сервису могут привязаться внешние приложения. Последний затем обеспечивает привязку к вашей службе только внешним приложениям, имеющим разрешениеandroid.permission.BIND_NFC_SERVICE
. Посколькуandroid.permission.BIND_NFC_SERVICE
является системным разрешением, это фактически обеспечивает привязку к вашей службе только ОС Android.
Ниже приведен пример объявления манифеста HostApduService
:
<service android:name=".MyHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"> <intent-filter> <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/> </intent-filter> <meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/apduservice"/> </service>
Этот тег метаданных указывает на файл apduservice.xml
. Ниже приведен пример такого файла с одним объявлением группы AID, содержащим два собственных AID:
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/servicedesc" android:requireDeviceUnlock="false"> <aid-group android:description="@string/aiddescription" android:category="other"> <aid-filter android:name="F0010203040506"/> <aid-filter android:name="F0394148148100"/> </aid-group> </host-apdu-service>
Тег <host-apdu-service>
должен содержать атрибут <android:description>
, содержащий понятное для пользователя описание службы, которое можно отобразить в пользовательском интерфейсе приложения. Вы можете использовать атрибут requireDeviceUnlock
, чтобы указать, что устройство разблокировано, прежде чем вы вызовете эту службу для обработки APDU.
<host-apdu-service>
должен содержать один или несколько тегов <aid-group>
. Каждый тег <aid-group>
должен выполнять следующие действия:
- Содержит атрибут
android:description
, содержащий понятное для пользователя описание группы AID, подходящее для отображения в пользовательском интерфейсе. - Установите атрибут
android:category
чтобы указать категорию, к которой принадлежит группа AID, например строковые константы, определенныеCATEGORY_PAYMENT
илиCATEGORY_OTHER
. - Содержит один или несколько тегов
<aid-filter>
, каждый из которых содержит один AID. Укажите AID в шестнадцатеричном формате и убедитесь, что он содержит четное количество символов.
Ваше приложение также должно иметь разрешение NFC
для регистрации в качестве службы HCE.
Разрешение конфликтов в рамках помощи
На одном устройстве можно установить несколько компонентов HostApduService
, и один и тот же AID может быть зарегистрирован более чем одной службой. Android определяет, какую службу вызывать, используя следующие шаги:
- Если выбранное пользователем приложение кошелька по умолчанию зарегистрировало AID, то это приложение вызывается.
- Если приложение кошелька по умолчанию не зарегистрировало AID, вызывается служба, зарегистрировавшая AID.
- Если AID зарегистрировано более чем в одной службе, Android спрашивает пользователя, какую службу вызвать.
Предпочтение службы переднего плана
Приложения на переднем плане могут вызывать setPreferredService
чтобы указать, какой сервис эмуляции карт следует предпочесть, пока определенное действие находится на переднем плане. Это предпочтение приложения переднего плана переопределяет разрешение конфликтов AID. Это рекомендуемая практика, если приложение предполагает, что пользователь может использовать эмуляцию карты NFC.
Андроид 13 и выше
Чтобы лучше соответствовать списку выбора платежей по умолчанию в пользовательском интерфейсе настроек, измените требование к баннеру на квадратный значок. В идеале он должен быть идентичен дизайну значка запуска приложения. Эта настройка обеспечивает большую последовательность и более чистый вид.
Android 12 и более ранние версии
Установите размер баннера службы на 260x96 dp, затем задайте размер баннера службы в XML-файле метаданных, добавив атрибут android:apduServiceBanner
к тегу <host-apdu-service>
, который указывает на ресурс, который можно рисовать. Ниже приведен пример:
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/servicedesc" android:requireDeviceUnlock="false" android:apduServiceBanner="@drawable/my_banner"> <aid-group android:description="@string/aiddescription" android:category="payment"> <aid-filter android:name="F0010203040506"/> <aid-filter android:name="F0394148148100"/> </aid-group> </host-apdu-service>
Приложения кошелька
Android 15 и более поздних версий включает роль приложения-кошелька по умолчанию, которую пользователь может выбрать, перейдя в «Настройки» > «Приложения» > «Приложения по умолчанию» . Это определяет приложение кошелька по умолчанию, которое будет вызываться при нажатии на платежный терминал. Android считает сервисы HCE, которые объявили группу AID с категорией оплаты, приложениями-кошельками .
Проверьте, является ли ваше приложение приложением-кошельком по умолчанию.
Приложения могут проверить, являются ли они приложением-кошельком по умолчанию, передав RoleManager.ROLE_WALLET
в RoleManager.isRoleHeld()
.
Если ваше приложение не является приложением по умолчанию, вы можете запросить роль кошелька по умолчанию, передав RoleManager.ROLE_WALLET
в RoleManager.createRequestRoleIntent()
.
Необходимые ресурсы для приложений кошелька
Чтобы обеспечить более визуально привлекательный пользовательский интерфейс, приложения-кошельки HCE должны иметь служебный баннер.
Режим наблюдения
В Android 15 представлена функция режима наблюдения . Если режим наблюдения включен, он позволяет устройству наблюдать за циклами опроса NFC и отправлять уведомления о них соответствующим компонентам HostApduService
, чтобы они могли подготовиться к взаимодействию с данным терминалом NFC. HostApduService
может перевести устройство в режим наблюдения, передав true
в setObserveModeEnabled()
. Это дает указание стеку NFC не разрешать транзакции NFC и вместо этого пассивно наблюдать за циклами опроса.
Фильтры контура опроса
Вы можете зарегистрировать фильтры цикла опроса для HostApduService
используя любой из следующих методов:
-
registerPollingLoopFilterForService()
для фильтров, которые должны точно соответствовать кадру опроса. -
registerPollingLoopPatternFilterForService()
для фильтров, которые соответствуют регулярному выражению в кадрах опроса.
Когда фильтр цикла опроса соответствует нестандартным кадрам опроса, стек NFC направляет эти кадры опроса в соответствующую HostApduService
, вызывая ее методprocessPollingFrames processPollingFrames()
. Это позволяет службе предпринять любые необходимые шаги, чтобы убедиться, что пользователь готов к транзакции и намеревается это сделать, например, аутентифицируя пользователя. Если считыватель NFC использует в своем цикле опроса только стандартные кадры, стек NFC направляет эти кадры опроса предпочтительной службе приоритетного плана, если эта служба находится на переднем плане, или держателю роли кошелька по умолчанию в противном случае.
Уведомления о кадрах опроса также включают в себя измерение напряженности поля, зависящее от поставщика, которое вы можете получить, вызвав getVendorSpecificGain()
. Поставщики могут предоставлять измерения, используя свою собственную шкалу, если она укладывается в один байт.
Реагировать на циклы опроса и выходить из режима наблюдения
Когда служба готова к транзакции, она может выйти из режима наблюдения, передав false
в setObserveModeEnabled()
. Стек NFC позволит продолжить транзакции.
Компоненты HostApduService
могут указать, что режим наблюдения должен быть включен всякий раз, когда они являются предпочтительной платежной службой, установив shouldDefaultToObserveMode
значение true
в манифесте или вызвав CardEmulation.setShouldDefaultToObserveModeForService()
.
Компоненты HostApduService
и OffHostApduService
также могут указывать, что фильтры цикла опроса, соответствующие полученным кадрам цикла опроса, должны автоматически отключать режим наблюдения и разрешать выполнение транзакций, установив для autoTransact
значение true
в объявлении PollingLoopFilter
в манифесте.
Предпочтение службы переднего плана
Приложения на переднем плане могут вызывать setPreferredService
чтобы указать, какой сервис эмуляции карт следует предпочесть, пока определенное действие находится на переднем плане. Эта настройка приложения переднего плана переопределяет состояние режима наблюдения устройства, соответствующее значению shouldDefaultToObserveMode
для данной службы, которое можно установить одним из следующих способов:
- Установка состояния
shouldDefaultToObserveMode
в манифесте этой службы. - Вызов
CardEmulation.setShouldDefaultToObserveModeForService()
с соответствующей службой и состоянием.
Выключение экрана и поведение экрана блокировки
Поведение служб HCE зависит от версии Android, установленной на устройстве.
Андроид 15 и выше
Если приложение кошелька по умолчанию включает режим наблюдения на устройстве, которое его поддерживает, то это приложение переопределяет поведение разблокировки и отключения экрана, поскольку оно контролирует, когда транзакция может быть продолжена. Некоторые приложения-кошельки могут потребовать, чтобы устройство было разблокировано, прежде чем транзакция сможет продолжиться, если режим наблюдения не обнаружил идентифицируемый шаблон цикла опроса.
Разработчикам рекомендуется работать со своими устройствами чтения, чтобы создавать идентифицируемые шаблоны циклов опроса, и регистрироваться для обработки этих шаблонов из своего приложения.
Андроид 12 и выше
В приложениях, предназначенных для Android 12 (уровень API 31) и выше, вы можете включить платежи NFC без включения экрана устройства, задав для requireDeviceScreenOn
значение false
.
Андроид 10 и выше
Устройства под управлением Android 10 (уровень API 29) или выше поддерживают Secure NFC . Когда Secure NFC включен, все эмуляторы карт (хостовые и внешние приложения) недоступны, когда экран устройства выключен. Когда Secure NFC отключен, автономные приложения доступны, когда экран устройства выключен. Вы можете проверить поддержку Secure NFC, используя isSecureNfcSupported()
.
На устройствах под управлением Android 10 и более поздних версий применяется та же функциональность для установки значения true
для android:requireDeviceUnlock
, что и на устройствах под управлением Android 9 и более поздних версий, но только в том случае, если Secure NFC отключен. То есть, если включен Secure NFC, службы HCE не смогут работать с экрана блокировки независимо от настройки android:requireDeviceUnlock
.
Андроид 9 и ниже
На устройствах под управлением Android 9 (уровень API 28) и ниже контроллер NFC и процессор приложений полностью отключаются при выключении экрана устройства. Поэтому службы HCE не работают, когда экран выключен.
Также на Android 9 и более ранних версиях службы HCE могут работать с экрана блокировки. Однако это контролируется атрибутом android:requireDeviceUnlock
в теге <host-apdu-service>
вашей службы HCE. По умолчанию разблокировка устройства не требуется, и ваша служба вызывается, даже если устройство заблокировано.
Если вы установите для атрибута android:requireDeviceUnlock
значение true
для службы HCE, Android предложит пользователю разблокировать устройство в следующих случаях:
- пользователь касается считывателя NFC.
- считыватель NFC выбирает AID, соответствующий вашему сервису.
После разблокировки Android отображает диалоговое окно, предлагающее пользователю нажать еще раз, чтобы завершить транзакцию. Это необходимо, поскольку пользователь мог отодвинуть устройство от считывателя NFC, чтобы разблокировать его.
Сосуществование с картами защищенных элементов
Этот раздел представляет интерес для разработчиков, которые развернули приложение, использующее элемент безопасности для эмуляции карты. Реализация HCE в Android предназначена для работы параллельно с другими методами реализации эмуляции карт, включая использование элементов безопасности.
Это сосуществование основано на принципе, называемом маршрутизацией AID . Контроллер NFC хранит таблицу маршрутизации, состоящую из (конечного) списка правил маршрутизации. Каждое правило маршрутизации содержит AID и пункт назначения. Местом назначения может быть либо центральный процессор, на котором работают приложения Android, либо подключенный защищенный элемент.
Когда считыватель NFC отправляет APDU с SELECT AID
, контроллер NFC анализирует его и проверяет, совпадают ли AID с каким-либо AID в его таблице маршрутизации. Если он совпадает, этот APDU и все последующие APDU отправляются в пункт назначения, связанный с AID, до тех пор, пока не будет получен другой APDU SELECT AID
или соединение NFC не разорвется.
Рисунок 4 иллюстрирует эту архитектуру:
Контроллер NFC обычно также содержит маршрут по умолчанию для APDU. Если AID не найден в таблице маршрутизации, используется маршрут по умолчанию. Хотя этот параметр может отличаться от устройства к устройству, устройства Android должны гарантировать, что идентификаторы AID, регистрируемые вашим приложением, правильно перенаправляются на хост.
Приложениям Android, реализующим службу HCE или использующим элемент безопасности, не нужно беспокоиться о настройке таблицы маршрутизации; это обрабатывается Android автоматически. Android просто нужно знать, какие AID могут обрабатываться службами HCE, а какие — элементом безопасности. Таблица маршрутизации настраивается автоматически в зависимости от того, какие службы установлены и какие пользователь настроил по своему усмотрению.
В следующем разделе объясняется, как объявить AID для приложений, использующих безопасный элемент для эмуляции карты.
Регистрация AID безопасного элемента
Приложения, использующие безопасный элемент для эмуляции карты, могут объявить внехостовую службу в своем манифесте. Объявление такой службы практически идентично объявлению службы HCE. Исключения следующие:
- Для действия, используемого в фильтре намерений, должно быть установлено значение
SERVICE_INTERFACE
. - Атрибут имени метаданных должен иметь значение
SERVICE_META_DATA
. XML-файл метаданных должен использовать корневой тег
<offhost-apdu-service>
.<service android:name=".MyOffHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"> <intent-filter> <action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/> </intent-filter> <meta-data android:name="android.nfc.cardemulation.off_host_apdu_service" android:resource="@xml/apduservice"/> </service>
Ниже приведен пример соответствующего файла apduservice.xml
, в котором регистрируются два AID:
<offhost-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/servicedesc"> <aid-group android:description="@string/subscription" android:category="other"> <aid-filter android:name="F0010203040506"/> <aid-filter android:name="F0394148148100"/> </aid-group> </offhost-apdu-service>
Атрибут android:requireDeviceUnlock
не применяется к службам вне хоста, поскольку ЦП узла не участвует в транзакции и, следовательно, не может помешать элементу безопасности выполнять транзакции, когда устройство заблокировано.
Атрибут android:apduServiceBanner
необходим для внешних служб, которые являются платежными приложениями, и его можно выбрать в качестве платежного приложения по умолчанию.
Вызов службы вне хоста
Android никогда не запускается и не привязывается к службе, которая объявлена как «внешняя», поскольку фактические транзакции выполняются элементом безопасности, а не службой Android. Объявление службы просто позволяет приложениям регистрировать AID, присутствующие в защищенном элементе.
HCE и безопасность
Архитектура HCE обеспечивает один основной элемент безопасности: поскольку ваш сервис защищен системным разрешением BIND_NFC_SERVICE
, только операционная система может связываться с вашим сервисом и взаимодействовать с ним. Это гарантирует, что любой полученный вами APDU на самом деле является APDU, полученным ОС от контроллера NFC, и что любой APDU, который вы отправляете обратно, поступает только в ОС, которая, в свою очередь, напрямую пересылает APDU на контроллер NFC.
Последняя оставшаяся проблема — откуда вы берете данные, которые ваше приложение отправляет на устройство чтения NFC. В конструкции HCE это намеренно отделено; его не волнует, откуда поступают данные, он просто следит за тем, чтобы они были безопасно перенесены в контроллер NFC и выведены в считывающее устройство NFC.
Для безопасного хранения и получения данных, которые вы хотите отправить из службы HCE, вы можете, например, использовать песочницу приложений Android, которая изолирует данные вашего приложения от других приложений. Дополнительные сведения о безопасности Android см. в статье Советы по безопасности .
Параметры и детали протокола
Этот раздел представляет интерес для разработчиков, которые хотят понять, какие параметры протокола используют устройства HCE на этапах антиколлизии и активации протоколов NFC. Это позволяет создать инфраструктуру чтения, совместимую с устройствами Android HCE.
Антиколлизия и активация протокола Nfc-A (ISO/IEC 14443 тип A)
В рамках активации протокола Nfc-A происходит обмен несколькими кадрами.
В первой части обмена устройство HCE представляет свой UID; Предполагается, что устройства HCE имеют случайный UID. Это означает, что при каждом нажатии UID, представляемый читателю, является случайно сгенерированным UID. По этой причине считыватели NFC не должны зависеть от UID устройств HCE как формы аутентификации или идентификации.
Устройство считывания NFC впоследствии может выбрать устройство HCE, отправив команду SEL_REQ
. В ответе SEL_RES
устройства HCE установлен как минимум 6-й бит (0x20), указывающий, что устройство поддерживает ISO-DEP. Обратите внимание, что другие биты в SEL_RES
также могут быть установлены, указывая, например, на поддержку протокола NFC-DEP (p2p). Поскольку могут быть установлены и другие биты, читатели, желающие взаимодействовать с устройствами HCE, должны явно проверять только 6-й бит, а не сравнивать полный SEL_RES
со значением 0x20.
Активация ISO-DEP
После активации протокола Nfc-A считыватель NFC инициирует активацию протокола ISO-DEP. Он отправляет команду RATS (запрос ответа на выбор). Контроллер NFC генерирует ответ RATS, ATS; ATS не настраивается службами HCE. Однако реализации HCE должны соответствовать требованиям NFC Forum для ответа ATS, поэтому считыватели NFC могут рассчитывать на то, что эти параметры будут установлены в соответствии с требованиями NFC Forum для любого устройства HCE.
В разделе ниже представлена более подробная информация об отдельных байтах ответа ATS, предоставляемого контроллером NFC на устройстве HCE:
- TL: длина ответа ATS. Не должно указывать длину более 20 байт.
- T0: биты 5, 6 и 7 должны быть установлены на всех устройствах HCE, указывая, что TA(1), TB(1) и TC(1) включены в ответ ATS. Биты с 1 по 4 обозначают FSCI, кодирующий максимальный размер кадра. На устройствах HCE значение FSCI должно находиться в диапазоне от 0h до 8h.
- T(A)1: определяет битрейт между считывателем и эмулятором, а также могут ли они быть асимметричными. Для устройств HCE не существует никаких требований или гарантий по скорости передачи данных.
- T(B)1: биты с 1 по 4 обозначают целое число времени защиты начального кадра (SFGI). На устройствах HCE SFGI должен быть <= 8h. Биты с 5 по 8 обозначают целое число времени ожидания кадра (FWI) и кодируют время ожидания кадра (FWT). На устройствах HCE FWI должен быть <= 8h.
- T(C)1: бит 5 указывает на поддержку «функций расширенного протокола». Устройства HCE могут поддерживать или не поддерживать «функции расширенного протокола». Бит 2 указывает на поддержку DID. Устройства HCE могут поддерживать или не поддерживать DID. Бит 1 указывает на поддержку NAD. Устройства HCE не должны поддерживать NAD и устанавливать бит 1 в ноль.
- Байты истории: устройства HCE могут возвращать до 15 байтов истории. Считыватели NFC, желающие взаимодействовать со службами HCE, не должны делать никаких предположений о содержании исторических байтов или их присутствии.
Обратите внимание, что многие устройства HCE, вероятно, соответствуют требованиям протокола, которые платежные сети, объединенные в EMVCo, указали в своей спецификации «Протокол бесконтактной связи». В частности:
- FSCI в T0 должен находиться в диапазоне от 2 до 8 часов.
- Для T(A)1 должно быть установлено значение 0x80, что указывает на то, что поддерживается только скорость передачи данных 106 кбит/с, а асимметричные скорости передачи данных между устройством чтения и эмулятором не поддерживаются.
- FWI в T(B)1 должно быть <= 7h.
Обмен данными APDU
Как отмечалось ранее, реализации HCE поддерживают только один логический канал. Попытка выбрать приложения на разных логических каналах не работает на устройстве HCE.