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 las versiones posteriores proporcionan un método adicional de emulación de tarjeta que no involucra un Elemento seguro, que se llama emulación de tarjeta 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 se proporciona la emulación de tarjeta NFC con un Elemento seguro, la tarjeta que se emula se aprovisiona en el Elemento seguro del dispositivo a través de 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:
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 una tarjeta NFC se emula mediante la emulación de tarjeta basada en host, los datos se enrutan directamente a la CPU del host en lugar de enrutarse a un Elemento seguro. En la Figura 2, se ilustra cómo funciona la emulación de tarjetas basada en el host:
Tarjetas y protocolos NFC compatibles
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 ilustran las capas 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. Si implementas una aplicación de HCE para Android, te recomendamos que registres un AID según el estándar 7816-5, ya que evita colisiones con otras aplicaciones.
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 algunos AID del grupo se puedan enrutar a un servicio de HCE y otros a otro.
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, a su vez, permite al usuario establecer valores predeterminados a nivel de categoría en lugar de 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:
CATEGORY_PAYMENT
(que cubre las apps de pagos estándares de la industria)CATEGORY_OTHER
(para todas las demás apps de HCE)
Implementa 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
, que contiene el AID con el que el lector quiere comunicarse. 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 que indica cuál de los dos ocurrió.
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, que, por lo general, se puede intercambiar 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:
Para indicarle a la plataforma que es un servicio de HCE que implementa una interfaz
HostApduService
, agrega un filtro de intents para la acciónSERVICE_INTERFACE
a la declaración de tu servicio.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.Configura el atributo
android:exported
comotrue
y solicita el permisoandroid.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 permisoandroid.permission.BIND_NFC_SERVICE
puedan vincularse. Comoandroid.permission.BIND_NFC_SERVICE
es un permiso del sistema, esto exige de forma eficaz 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 fácil de usar y que 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>
se requiere para hacer 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 porCATEGORY_PAYMENT
oCATEGORY_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.
La aplicación también debe tener el permiso NFC
para registrarse como un servicio de HCE.
Resolución de conflictos de AID
Se pueden instalar varios componentes HostApduService
en un solo dispositivo, y más de un servicio puede registrar el mismo AID. Android determina cuál servicio invocar mediante los siguientes pasos:
- Si la app de billetera predeterminada que seleccionó el usuario registró el AID, se invocará esa app.
- Si la app de billetera predeterminada no registró el AID, se invoca el servicio que lo registró.
- Si más de un servicio registró el AID, Android le preguntará al usuario qué servicio debe invocar.
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()
.
Aplicaciones de la Billetera
Android considera como aplicaciones de billetera a los servicios de HCE que declararon un grupo de AID con la categoría de pago. Android 15 y las versiones posteriores incluyen un rol de app de billetera predeterminada que el usuario puede seleccionar navegando a Configuración > Apps > Apps predeterminadas. Esto define la aplicación de billetera predeterminada que se invocará cuando se presione una terminal de pago.
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.
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>
Modo de observación
En Android 15, se introduce 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 NFC que no permita las transacciones NFC y que, en su lugar, observe de forma pasiva los bucles de sondeo.
Filtros de bucle de sondeo
Puedes registrar los filtros de bucle de sondeo para un HostApduService
mediante cualquiera de los siguientes métodos:
registerPollingLoopFilterForService()
para los filtros que deben coincidir exactamente con un marco de sondeo.registerPollingLoopPatternFilterForService()
para los filtros que coinciden con una expresión regular con los marcos de sondeo.
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, autenticándolo. 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.
Responder a los bucles de sondeo y salir del modo de observación
Cuando el servicio esté listo para realizar transacciones, puede salir del modo de observación pasando false
a setObserveModeEnabled()
. La pila 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
como true
en la declaración PollingLoopFilter
del manifiesto.
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 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 NFC seguro está desactivada. Es decir, si la función NFC seguro 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 aplicaciones 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 se requiere el desbloqueo del dispositivo, y se invoca tu servicio incluso si 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:
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 de forma automática según los servicios instalados y los que el usuario configuró 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 usan un Elemento seguro para la emulación de 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 se pueden seleccionar como aplicación de pagos predeterminada.
Invocación de servicios fuera del host
Android nunca inicia un servicio que se declara como "fuera del host" ni se vincula a él, ya que el Elemento seguro ejecuta las transacciones reales y 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 una pieza fundamental de seguridad: debido a que 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 quieres enviar desde tu servicio de HCE, puedes, por ejemplo, utilizar la zona de pruebas de aplicaciones para Android, que aísla los datos de tu app de otras apps. Para obtener más detalles sobre la seguridad de Android, consulta las 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 compilar una infraestructura de lector que sea compatible con 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). Como se pueden configurar otros bits, los lectores que deseen interactuar con dispositivos con HCE deben verificar 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 se deben configurar 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 "funciones avanzadas de protocolo". 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 señaló antes, las implementaciones de HCE solo admiten un canal lógico. Intentar seleccionar aplicaciones en diferentes canales lógicos no funciona en un dispositivo con HCE.