Descripción general de la emulación de tarjeta basada en el host

Muchos dispositivos con Android que ofrecen la función de NFC ya admiten la emulación de tarjetas NFC. En la mayoría de los casos, el dispositivo tiene un chip separado llamado Elemento seguro que emula la tarjeta. Muchas de las tarjetas SIM que brindan los proveedores de servicios inalámbricos también contienen un Elemento seguro.

Android 4.4 y versiones posteriores proporcionan un método adicional de emulación de tarjetas que no involucra un Elemento seguro, que se llama emulación de tarjetas basada en host. Esto permite que cualquier aplicación para Android emule una tarjeta y se comunique directamente con el lector de NFC. En este tema, se describe cómo funciona la emulación de tarjetas basada en el host (HCE) en Android y cómo usar esta técnica para desarrollar una app que emule una tarjeta NFC.

Emulación de tarjetas con un Elemento seguro

Cuando la emulación de tarjetas NFC se realiza a través de un Elemento seguro, los datos de la tarjeta que se emulará se almacenan en el Elemento seguro del dispositivo mediante una aplicación para Android. Luego, cuando el usuario acerca el dispositivo a una terminal NFC, el controlador de NFC del dispositivo enruta todos los datos del lector directamente al Elemento seguro. En la figura 1, se ilustra este concepto:

Diagrama con un lector de NFC que pasa por un controlador de NFC para recuperar información de un elemento seguro
Figura 1: Emulación de tarjeta NFC con un Elemento seguro

El Elemento seguro se comunica con la terminal NFC sin que intervenga ninguna aplicación para Android en la transacción. Una vez completada la transacción, la app puede enviar una consulta directamente al Elemento seguro para conocer el estado de la transacción y comunicárselo al usuario.

Emulación de tarjetas basada en el host

Cuando se emula una tarjeta NFC mediante la emulación basada en el host, los datos se enrutan directamente a la CPU del host en lugar de a un elemento seguro. En la figura 2, se ilustra cómo funciona la emulación de tarjetas basada en el host:

Diagrama con un lector de NFC que pasa por un controlador de NFC para recuperar información de la CPU
Figura 2: Emulación de tarjeta NFC sin un Elemento seguro

Tarjetas y protocolos NFC compatibles

Diagrama que muestra la pila de protocolos HCE
Figura 3: Pila de protocolos HCE de Android

Los estándares de NFC ofrecen compatibilidad con muchos protocolos diferentes, y se pueden emular varios tipos de tarjetas.

Android 4.4 y versiones posteriores admiten varios protocolos que son comunes en el mercado actual. Muchas tarjetas que usan la tecnología sin contacto ya se basan en estos protocolos, como las tarjetas de pago sin contacto. Los protocolos también son compatibles con diferentes lectores de NFC del mercado actual, incluidos los dispositivos con NFC de Android que funcionan como lectores (consulta la clase IsoDep). De esa forma, puedes crear e implementar una solución NFC de principio a fin en torno a HCE utilizando solo dispositivos con Android.

En particular, Android 4.4 y versiones posteriores admiten la emulación de tarjetas que se basan en la especificación ISO-DEP de NFC Forum (basada en ISO/IEC 14443-4) y procesar unidades de datos de protocolo de aplicación (APDU) definidas en la especificación ISO/IEC 7816-4. Android exige la emulación de ISO-DEP solo por encima de la tecnología Nfc-A (ISO/IEC 14443-3 tipo A). La compatibilidad con la tecnología NFC-B (ISO/IEC 14443-4 tipo B) es opcional. En la figura 3, se ilustra la superposición de todas estas especificaciones.

Servicios de HCE

La arquitectura de HCE en Android se basa en los componentes Service de Android (conocidos como servicios de HCE). Una de las principales ventajas de un servicio es que se puede ejecutar en segundo plano sin una interfaz de usuario. Este es un comportamiento natural para muchas aplicaciones de HCE, como las de tarjetas de transporte público o de lealtad. En esos casos, el usuario no debería abrir la app para usarla. En su lugar, cuando se presiona el dispositivo contra el lector de NFC, se inicia el servicio correcto si aún no está en ejecución y se ejecuta la transacción en segundo plano. Por supuesto, puedes iniciar IU adicionales (como notificaciones para el usuario) desde tu servicio cuando corresponda.

Selección de servicios

Cuando el usuario toca un dispositivo con un lector de NFC, el sistema Android necesita saber con qué servicio de HCE desea comunicarse el lector de NFC. La especificación ISO/IEC 7816-4 define una forma de seleccionar aplicaciones centrada en un ID de aplicación (AID). Un AID consta de hasta 16 bytes. Si estás emulando tarjetas para una infraestructura de lector de NFC ya existente, los AID que buscan esos lectores, a menudo, son conocidos y están registrados de manera pública (por ejemplo, los AID de redes de pagos como Visa y MasterCard).

Si quieres implementar una nueva infraestructura de lector para tu aplicación, debes registrar tus propios AID. El procedimiento de registro de los AID se define en la especificación ISO/IEC 7816-5. Recomendamos registrar un AID según 7816-5 si vas a implementar una aplicación de HCE para Android, ya que evita las colisiones con otras apps.

Grupos de AID

En algunos casos, es posible que un servicio de HCE deba registrar varios AID y establecerse como el controlador predeterminado de todos los AID para implementar una aplicación determinada. No se admiten algunos AID del grupo que se dirigen a otro servicio.

Una lista de AIDs que se mantienen juntos se denomina grupo de AID. Android garantiza una de las siguientes opciones a todos los AID de un grupo:

  • Todos los AID del grupo se enrutan a este servicio de HCE.
  • No se enruta ningún AID del grupo a este servicio de HCE (por ejemplo, porque el usuario prefirió otro servicio que también solicitó uno o más AID de tu grupo).

En otras palabras, no existe un estado intermedio en el que los AID del grupo se puedan distribuir a diferentes servicios de HCE.

Grupos y categorías de AID

Puedes asociar cada grupo de AID con una categoría. Esto permite que Android agrupe los servicios de HCE por categoría y, por consiguiente, que el usuario establezca valores predeterminados en el nivel de categoría en lugar de en el nivel del AID. Evita mencionar los AIDs en cualquier sector de tu aplicación que vea el usuario promedio, ya que no representan nada para ellos.

Android 4.4 y versiones posteriores admiten dos categorías:

Cómo implementar un servicio de HCE

Para emular una tarjeta NFC mediante la emulación de tarjetas basada en host, debes crear un componente Service que maneje las transacciones con NFC.

Cómo comprobar la compatibilidad con HCE

Tu aplicación puede verificar si un dispositivo es compatible con HCE si comprueba la función FEATURE_NFC_HOST_CARD_EMULATION. Usa la etiqueta <uses-feature> en el manifiesto de la aplicación para declarar que usa la función HCE y si la necesita o no para funcionar.

Implementación del servicio

Android 4.4 y versiones posteriores proporcionan una clase Service de conveniencia que puedes usar como base para implementar un servicio de HCE: la clase HostApduService.

El primer paso es extender HostApduService, como se muestra en la siguiente muestra de código:

Kotlin

class MyHostApduService : HostApduService() {

    override fun processCommandApdu(commandApdu: ByteArray, extras: Bundle?): ByteArray {
       ...
    }

    override fun onDeactivated(reason: Int) {
       ...
    }
}

Java

public class MyHostApduService extends HostApduService {
    @Override
    public byte[] processCommandApdu(byte[] apdu, Bundle extras) {
       ...
    }
    @Override
    public void onDeactivated(int reason) {
       ...
    }
}

HostApduService declara dos métodos abstractos que debes anular e implementar. Se llama a uno de ellos, processCommandApdu(), cada vez que un lector de NFC envía una unidad de datos del protocolo de aplicación (APDU) a tu servicio. Las APDU se definen en la especificación ISO/IEC 7816-4. Son los paquetes de nivel de aplicación que se intercambian entre el lector de NFC y tu servicio de HCE. Ese protocolo de nivel de aplicación es de dúplex medio: el lector de NFC te envía una APDU de comando y espera a que envíes una APDU de respuesta.

Como ya se mencionó, Android usa el AID para determinar con qué servicio de HCE se quiere comunicar el lector. Por lo general, la primera APDU que envía un lector de NFC a tu dispositivo es una APDU SELECT AID. Esta APDU contiene el AID con el que el lector se quiere comunicar. Android extrae ese AID de la APDU, lo resuelve en un servicio de HCE y luego reenvía esa APDU al servicio resuelto.

Puedes enviar una APDU de respuesta si muestras los bytes de la APDU de respuesta de processCommandApdu(). Ten en cuenta que se llama a este método en el subproceso principal de tu aplicación, que no debes bloquear. Si no puedes calcular y mostrar una APDU de respuesta de inmediato, muestra un valor nulo. Luego, puedes realizar el trabajo necesario en otro subproceso y usar el método sendResponseApdu() definido en la clase HostApduService para enviar la respuesta cuando hayas terminado.

Android seguirá reenviando nuevas APDU del lector a tu servicio hasta que se dé una de estas dos situaciones:

  • El lector de NFC envía otra APDU SELECT AID, que el SO resuelve en un servicio diferente.
  • Deja de funcionar el vínculo de NFC entre el lector de NFC y tu dispositivo.

En ambos casos, se llama a la implementación de onDeactivated() de tu clase con un argumento en el que se indica qué sucedió.

Si estás trabajando con una infraestructura de lector existente, debes implementar el protocolo de nivel de aplicación que esperan los lectores en tu servicio de HCE.

Si vas a implementar una nueva infraestructura de lector que también controlas, puedes definir un protocolo y una secuencia de APDU propios. Intenta limitar la cantidad de APDU y el tamaño de los datos que se intercambiarán. De este modo, te asegurarás de que los usuarios solo tengan que mantener su dispositivo sobre el lector de NFC durante poco tiempo. Un límite superior razonable es de aproximadamente 1 KB de datos, una cantidad que, en general, se puede cambiar en 300 ms.

Declaración del servicio en el manifiesto y registro del AID

Debes declarar tu servicio en el manifiesto como de costumbre, pero también debes agregar algunos elementos adicionales a la declaración del servicio:

  1. Para indicarle a la plataforma que es un servicio de HCE que implementa una interfaz HostApduService, agrega un filtro de intents para la acción SERVICE_INTERFACE a la declaración de tu servicio.

  2. Para indicarle a la plataforma qué grupos de AID solicita este servicio, incluye una etiqueta SERVICE_META_DATA <meta-data> en la declaración del servicio que dirija a un recurso XML con información adicional sobre el servicio de HCE.

  3. Establece el atributo android:exported en true y solicita el permiso android.permission.BIND_NFC_SERVICE en la declaración del servicio. El primero garantiza que las aplicaciones externas puedan vincularse al servicio. El segundo exige que solo las aplicaciones externas que tienen el permiso android.permission.BIND_NFC_SERVICE puedan vincularse. Dado que android.permission.BIND_NFC_SERVICE es un permiso del sistema, exige que solo el SO Android pueda vincularse a tu servicio.

El siguiente es un ejemplo de una declaración de manifiesto 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>

Esta etiqueta de metadatos dirige a un archivo apduservice.xml. A continuación, se muestra un ejemplo de un archivo con una declaración de un solo grupo de AID que contiene dos AID de propiedad:

<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>

La etiqueta <host-apdu-service> debe contener un atributo <android:description> que incluya una descripción del servicio que sea sencilla y puedas mostrar en la IU de la app. Puedes usar el atributo requireDeviceUnlock para especificar que el dispositivo está desbloqueado antes de invocar este servicio para controlar las APDU.

El <host-apdu-service> debe contener una o más etiquetas <aid-group>. Cada etiqueta <aid-group> debe cumplir con lo siguiente:

  • Debe incluir un atributo android:description que contenga una descripción del grupo de AID sencilla y adecuada para mostrarse en la IU.
  • Debe tener su atributo android:category establecido para indicar la categoría a la que pertenece el grupo de AID, como las constantes de cadenas definidas por CATEGORY_PAYMENT o CATEGORY_OTHER.
  • Contiene una o más etiquetas <aid-filter>, cada una de las cuales contiene un AID único. Especifica el AID en formato hexadecimal y asegúrate de que contenga un número par de caracteres.

Tu aplicación también debe tener el permiso NFC para registrarse como servicio de HCE.

Resolución de conflictos de AID

Se pueden instalar varios componentes HostApduService en un solo dispositivo y varios servicios pueden registrar el mismo AID. Android determina cuál servicio invocar mediante los siguientes pasos:

  1. Si la app de billetera predeterminada que seleccionó el usuario registró el AID, se invocará esa app.
  2. Si la app de billetera predeterminada no registró el AID, se invoca el servicio que lo registró.
  3. Si más de un servicio registró el AID, Android le pregunta al usuario qué servicio invocar.

Preferencia del servicio en primer plano

Las apps en primer plano pueden invocar setPreferredService para especificar qué servicio de emulación de tarjeta debe preferirse mientras una actividad específica está en primer plano. Esta preferencia de app en primer plano anula la resolución de conflictos de AID. Esta es una práctica recomendada cuando la app anticipa que el usuario podría usar la emulación de tarjeta NFC.

Android 13 y versiones posteriores

Para que se ajuste mejor a la lista de selección de pagos predeterminada en la IU de Configuración, ajusta el requisito del banner a un ícono cuadrado. Idealmente, debería ser idéntico al diseño del ícono del selector de la aplicación. Este ajuste crea más coherencia y un aspecto más ordenado.

Android 12 y versiones anteriores

Establece el tamaño del banner del servicio en 260 x 96 dp y, luego, agrega el atributo android:apduServiceBanner a la etiqueta <host-apdu-service>, que dirige al recurso de diseño, para establecer el tamaño del banner del servicio en tu archivo XML de metadatos. El siguiente es un ejemplo:

<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>

Aplicaciones de billetera

Android 15 y las versiones posteriores incluyen un rol predeterminado de la app de billetera que el usuario puede seleccionar si navega a Configuración > Apps > Apps predeterminadas. Esto define la aplicación de billetera predeterminada que se invocará cuando se presione una terminal de pago. Android considera como aplicaciones de billetera a los servicios de HCE que declararon un grupo de AID con la categoría de pago.

Verifica si tu app es la app de billetera predeterminada

Las apps pueden verificar si son la app de billetera predeterminada pasando RoleManager.ROLE_WALLET a RoleManager.isRoleHeld().

Si tu app no es la predeterminada, puedes solicitar el rol de billetera predeterminado pasando RoleManager.ROLE_WALLET a RoleManager.createRequestRoleIntent().

Recursos obligatorios para aplicaciones de billetera

Para ofrecer una experiencia del usuario más atractiva visualmente, las aplicaciones de billetera con HCE deben proporcionar un banner de servicio.

Modo de observación

Android 15 presenta la función Modo de observación. Cuando está habilitado, el modo de observación permite que el dispositivo observe los bucles de sondeo de NFC y envíe notificaciones sobre ellos a los componentes HostApduService adecuados para que se preparen para interactuar con una terminal NFC determinada. Un HostApduService puede poner el dispositivo en modo de observación pasando true a setObserveModeEnabled(). Esto le indica a la pila de NFC que no permita transacciones de NFC y, en su lugar, observe pasivamente los bucles de sondeo.

Filtros de bucle de sondeo

Puedes registrar filtros de bucle de sondeo para un HostApduService con cualquiera de los siguientes métodos:

Cuando un filtro de bucle de sondeo coincide con tramas de sondeo no estándar, la pila de NFC enruta esas tramas de sondeo al HostApduService correspondiente llamando a su método processPollingFrames(). Esto permite que el servicio tome los pasos necesarios para garantizar que el usuario esté listo para realizar transacciones y tenga la intención de hacerlo, por ejemplo, autenticarlo. Si un lector de NFC usa solo tramas estándar en su bucle de sondeo, la pila de NFC enruta esas tramas de sondeo al servicio en primer plano preferido si ese servicio está en primer plano o al titular de rol de billetera predeterminado de lo contrario.

Las notificaciones de marco de sondeo también incluyen una medición específica del proveedor de la intensidad del campo que puedes recuperar llamando a getVendorSpecificGain(). Los proveedores pueden proporcionar mediciones con su propia escala, siempre que se ajusten a un solo byte.

Responde a los bucles de sondeo y sale del modo de observación

Cuando el servicio esté listo para realizar transacciones, puede salir del modo de observación pasando false a setObserveModeEnabled(). Luego, la pila de NFC permitirá que las transacciones continúen.

Los componentes HostApduService pueden indicar que se debe habilitar el modo de observación cuando son el servicio de pago preferido. Para ello, configura shouldDefaultToObserveMode como true en el manifiesto o llama a CardEmulation.setShouldDefaultToObserveModeForService().

Los componentes HostApduService y OffHostApduService también pueden indicar que los filtros de bucle de sondeo que coinciden con las tramas de bucle de sondeo recibidas deben inhabilitar automáticamente el modo de observación y permitir que las transacciones continúen configurando autoTransact en true en la declaración PollingLoopFilter del manifiesto.

Preferencia del servicio en primer plano

Las apps en primer plano pueden invocar setPreferredService para especificar qué servicio de emulación de tarjeta debe preferirse mientras una actividad específica está en primer plano. Esta preferencia de app en primer plano anula el estado del modo de observación del dispositivo correspondiente al valor de shouldDefaultToObserveMode para un servicio determinado, que se puede establecer de una de las siguientes maneras:

Pantalla apagada y comportamiento de pantalla de bloqueo

El comportamiento de los servicios de HCE varía según la versión de Android que se ejecute en el dispositivo.

Android 15 y versiones posteriores

Si la app de billetera predeterminada activa el modo de observación en un dispositivo que lo admite, esa app anula el comportamiento de desbloqueo y de apagado de la pantalla, ya que controla cuándo se puede continuar una transacción. Es posible que algunas apps de billetera requieran que el dispositivo esté desbloqueado antes de que se pueda realizar una transacción si el modo de observación no detectó un patrón de bucle de sondeo identificable.

Se recomienda a los desarrolladores que trabajen con sus dispositivos de lectura para emitir patrones de bucle de sondeo identificables y registrarse para controlar esos patrones desde su app.

Android 12 y versiones posteriores

En las apps que se orientan a Android 12 (nivel de API 31) y versiones posteriores, puedes habilitar los pagos mediante NFC sin que la pantalla del dispositivo esté encendida. Para ello, configura requireDeviceScreenOn en false.

Android 10 y versiones posteriores

Los dispositivos que ejecutan Android 10 (nivel de API 29) o versiones posteriores admiten NFC seguro. Mientras el NFC seguro está activado, todos los emuladores de tarjetas (aplicaciones de host y fuera del host) no están disponibles cuando la pantalla del dispositivo está apagada. Mientras el NFC seguro está desactivado, las aplicaciones fuera del host están disponibles cuando la pantalla del dispositivo está apagada. Puedes verificar la compatibilidad con NFC seguro con isSecureNfcSupported().

En dispositivos que ejecutan Android 10 y versiones posteriores, se aplica la misma funcionalidad para configurar android:requireDeviceUnlock en true que con dispositivos que ejecutan Android 9 y versiones anteriores, pero solo cuando la función Proteger NFC está desactivada. Es decir, si la función Proteger NFC está activada, los servicios de HCE no pueden funcionar desde la pantalla de bloqueo, independientemente de la configuración de android:requireDeviceUnlock.

Android 9 y versiones anteriores

En dispositivos que ejecutan Android 9 (nivel de API 28) y versiones anteriores, el controlador de NFC y el procesador de la aplicación se apagan por completo cuando la pantalla del dispositivo está apagada. Por lo tanto, los servicios de HCE no funcionan cuando la pantalla está apagada.

Además, en Android 9 y versiones anteriores, los servicios de HCE pueden funcionar desde la pantalla de bloqueo. Sin embargo, esto se controla mediante el atributo android:requireDeviceUnlock de la etiqueta <host-apdu-service> de tu servicio de HCE. De forma predeterminada, no es obligatorio desbloquear la pantalla y se invoca el servicio aun cuando el dispositivo esté bloqueado.

Si configuras el atributo android:requireDeviceUnlock como true para tu servicio de HCE, Android le solicita al usuario que desbloquee el dispositivo cuando suceda lo siguiente:

  • el usuario presiona un lector de NFC.
  • El lector de NFC selecciona un AID que se resuelve en tu servicio.

Después de desbloquear el dispositivo, Android muestra un diálogo para pedirle al usuario que vuelva a presionar para completar la transacción. Esto es necesario porque el usuario puede haber movido el dispositivo fuera del lector de NFC para desbloquearlo.

Coexistencia con tarjetas que tienen Elemento seguro

Esta sección es de interés para los desarrolladores que implementaron una aplicación que necesita un Elemento seguro para emular una tarjeta. La implementación de HCE de Android está diseñada para funcionar en paralelo con otros métodos de implementación de la emulación de tarjetas, incluido el uso de Elementos seguros.

Esta coexistencia se basa en un principio llamado enrutamiento AID. El controlador de NFC mantiene una tabla de enrutamiento que consiste en una lista (finita) de reglas de enrutamiento. Cada una de ellas contiene un AID y un destino. El destino puede ser la CPU del host, donde se ejecutan las apps para Android, o un elemento seguro conectado.

Cuando el lector de NFC envía una APDU con un SELECT AID, el controlador de NFC la analiza y verifica si los AID coinciden con cualquier AID en su tabla de enrutamiento. Si coincide, esa APDU y todas las APDU siguientes se enviarán al destino asociado con el AID hasta que se reciba otra APDU SELECT AID o se corte el vínculo con NFC.

En la figura 4, se ilustra esta arquitectura:

Diagrama con un lector de NFC que se comunica con un elemento seguro y la CPU
Figura 4: Funcionamiento de Android con un Elemento seguro y con la emulación de tarjetas basada en el host

Por lo general, el controlador de NFC también contiene una ruta predeterminada para las APDU. Cuando no se encuentra un AID en la tabla de enrutamiento, se utiliza la ruta predeterminada. Si bien esta configuración puede variar en función del dispositivo, los dispositivos Android deben garantizar que los AID que registra tu app se enruten correctamente al host.

Las aplicaciones para Android que implementan un servicio de HCE o que usan un Elemento seguro no necesitan configurar la tabla de enrutamiento, ya que Android lo hace automáticamente. Android solo tiene que saber cuáles son los AID que pueden manejar los servicios de HCE y cuáles puede manejar el Elemento seguro. La tabla de enrutamiento se configura automáticamente en función de los servicios instalados y los que el usuario haya establecido como preferidos.

En la siguiente sección, se explica cómo declarar AID para aplicaciones que usan un elemento seguro en la emulación de tarjetas.

Registro de AID con Elementos seguros

Las aplicaciones que utilizan un Elemento seguro para emular tarjetas pueden declarar un servicio fuera del host en su manifiesto. La declaración de dicho servicio es casi idéntica a la de un servicio de HCE. Las excepciones son las siguientes:

  • La acción que se usa en el filtro de intents debe establecerse en SERVICE_INTERFACE.
  • El atributo de nombre de los metadatos debe establecerse en SERVICE_META_DATA.
  • El archivo XML de metadatos debe usar la etiqueta raíz <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>

El siguiente es un ejemplo del archivo apduservice.xml correspondiente que registra dos 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>

El atributo android:requireDeviceUnlock no se aplica a los servicios fuera del host, ya que la CPU del host no participa en la transacción y, por lo tanto, no puede evitar que el Elemento seguro ejecute transacciones cuando el dispositivo está bloqueado.

El atributo android:apduServiceBanner es obligatorio para los servicios fuera del host que son aplicaciones de pagos y para que se puedan seleccionar como una aplicación de pagos predeterminada.

Invocación de servicio fuera del host

Android nunca inicia un servicio que se declare como "fuera del host" ni se vincula con él, ya que el Elemento seguro es el que ejecuta las transacciones en sí, no el servicio de Android. La declaración del servicio solo permite que las aplicaciones registren los AID presentes en el Elemento seguro.

HCE y seguridad

La arquitectura de HCE proporciona un aspecto de seguridad básico: como tu servicio está protegido por el permiso del sistema BIND_NFC_SERVICE, solo el SO puede vincularse y comunicarse con él. Esto garantiza que cualquier APDU que recibas sea una APDU que recibió el SO desde el controlador de NFC y que cualquier APDU que envíes de vuelta solo vaya al SO, el cual, a su vez, reenviará directamente las APDU al controlador de NFC.

El último problema que queda es dónde obtienes los datos que envía tu app al lector de NFC. Esto se desacopla de forma intencional en el diseño de HCE: no le importa de dónde provienen los datos; solo se asegura de que se transporten de manera segura al controlador de NFC y al lector de NFC.

Para almacenar y recuperar de forma segura los datos que deseas enviar desde tu servicio de HCE, puedes, por ejemplo, utilizar la zona de pruebas de aplicaciones para Android, que aísla de otras apps los datos de tu app. Para obtener más detalles sobre la seguridad de Android, consulta el artículo Sugerencias de seguridad.

Parámetros y detalles del protocolo

Esta sección está orientada a los desarrolladores que desean comprender qué parámetros de protocolo utilizan los dispositivos con HCE durante las fases de anticolisión y activación de los protocolos de NFC. Esto permite construir una infraestructura de lector que sea compatible con los dispositivos Android con HCE.

Anticolisión y activación del protocolo Nfc-A (ISO/IEC 14443 tipo A)

Como parte de la activación del protocolo Nfc-A, se intercambian múltiples tramas.

En la primera parte del intercambio, el dispositivo con HCE presenta su UID; se debe suponer que los dispositivos con HCE tienen un UID aleatorio. Esto significa que, cada vez que el dispositivo toque el lector, el UID que se presente será un UID generado de forma aleatoria. Por tal motivo, los lectores de NFC no deben depender del UID de los dispositivos con HCE como una forma de autenticación o identificación.

Después, el lector de NFC puede seleccionar el dispositivo con HCE enviando un comando SEL_REQ. La respuesta SEL_RES del dispositivo con HCE tiene al menos el sexto bit (0x20) establecido, lo que indica que el dispositivo es compatible con ISO-DEP. Ten en cuenta que también se pueden establecer otros bits en SEL_RES, lo que indica, por ejemplo, compatibilidad con el protocolo NFC-DEP (p2p). Debido a que se pueden establecer otros bits, los lectores que deseen interactuar con dispositivos con HCE deberán buscar explícitamente solo el sexto bit y no comparar el SEL_RES completo con un valor de 0x20.

Activación de ISO-DEP

Después de activar el protocolo Nfc-A, el lector de NFC inicia la activación del protocolo ISO-DEP. Envía un comando RATS (solicitud de respuesta para seleccionar). El controlador NFC genera la respuesta RATS, la ATS, y los servicios de HCE no la pueden configurar. Sin embargo, las implementaciones de HCE deben cumplir con los requisitos de NFC Forum para la respuesta ATS, por lo que los lectores de NFC pueden contar con que estos parámetros se establezcan de acuerdo con lo que exige NFC Forum para cualquier dispositivo con HCE.

En la siguiente sección, se proporcionan más detalles sobre los bytes individuales de la respuesta ATS que brinda el controlador de NFC en un dispositivo con HCE:

  • TL: Es la longitud de la respuesta ATS. No debe indicar una longitud superior a 20 bytes.
  • T0: Los bits 5, 6 y 7 deben establecerse en todos los dispositivos con HCE, lo que indica que TA(1), TB(1) y TC(1) están incluidos en la respuesta ATS. Los bits 1 a 4 indican el FSCI, que codifica el tamaño máximo de trama. En los dispositivos con HCE, el valor del FSCI debe ser de entre 0 h y 8 h.
  • T(A)1: Define las tasas de bits entre el lector y el emulador, y si pueden ser asimétricas. No hay garantías ni requisitos de tasas de bits para los dispositivos con HCE.
  • T(B)1: Los bits 1 a 4 indican el número entero del tiempo de seguridad de la trama de inicio (SFGI). En dispositivos con HCE, el SFGI debe ser <= 8 h. Los bits 5 a 8 indican el número entero de tiempo de espera de la trama (FWI) y codifican el tiempo de espera de la trama (FWT). En dispositivos con HCE, el FWI debe ser <= 8 h.
  • T(C)1: El bit 5 indica compatibilidad con las funciones avanzadas del protocolo. Los dispositivos con HCE pueden o no admitir estas funciones. El bit 2 indica compatibilidad con el DID. Los dispositivos con HCE pueden o no ser compatibles con el DID. El bit 1 indica compatibilidad con la NAD. Los dispositivos con HCE no deben admitir la NAD y deben establecer el bit 1 en cero.
  • Bytes históricos: Los dispositivos con HCE pueden mostrar hasta 15 bytes históricos. Los lectores de NFC que deseen interactuar con los servicios de HCE no deben hacer suposiciones sobre el contenido de los bytes históricos ni sobre su presencia.

Ten en cuenta que muchos dispositivos con HCE tal vez cumplan con los requisitos de protocolo que las redes de pagos agrupadas en EMVCo definieron en la especificación de su protocolo de comunicación sin contacto. En particular:

  • El FSCI en T0 debe ser de entre 2 h y 8 h.
  • T(A)1 debe establecerse en 0x80, lo que indica que solo se admite la tasa de bits de 106 kbit/s, y las tasas de bits asimétricas entre el lector y el emulador no son compatibles.
  • El FWI en T(B)1 debe ser <= 7 h.

Intercambio de datos de APDU

Como se indicó anteriormente, las implementaciones de HCE solo admiten un canal lógico único. Intentar seleccionar aplicaciones en diferentes canales lógicos no funciona en un dispositivo con HCE.