Visão geral da emulação de cartão baseada em host

Muitos dispositivos Android que oferecem a funcionalidade NFC já são compatíveis com a emulação de cartão NFC. Na maioria dos casos, o cartão é emulado por um chip separado no dispositivo, chamado de elemento de segurança. Muitos chips fornecidos por operadoras de celular também contêm um elemento de segurança.

O Android 4.4 e versões mais recentes oferecem um método adicional de emulação de cartão que não envolve um elemento de segurança, chamado de emulação de cartão com base no host. Dessa forma, qualquer aplicativo Android pode emular um cartão e se comunicar diretamente com o leitor de NFC. Este tópico descreve como a emulação de cartão com base no host (HCE, na sigla em inglês) funciona no Android e como você pode desenvolver um app que emula um cartão NFC usando essa técnica.

Emulação de cartão com um elemento de segurança

Quando a emulação de cartão de NFC é fornecida usando um elemento de segurança, o cartão a ser emulado é provisionado no elemento de segurança no dispositivo por meio de um aplicativo Android. Em seguida, quando o usuário segura o dispositivo sobre um terminal de NFC, o controlador de NFC no dispositivo roteia todos os dados do leitor diretamente para o elemento de segurança. A Figura 1 ilustra esse conceito:

Diagrama com leitor de NFC passando por um controlador de NFC para extrair informações de um elemento de segurança
Figura 1. Emulação de cartão de NFC com um elemento de segurança.

O próprio elemento de segurança realiza a comunicação com o terminal de NFC e nenhum aplicativo Android está envolvido na transação. Depois que a transação é concluída, um aplicativo Android pode consultar o elemento de segurança diretamente para ver o status da transação e notificar o usuário.

Emulação de cartão com base no host

Quando um cartão de NFC é emulado usando emulação de cartão com base no host, os dados são roteados diretamente para a CPU do host em vez de serem roteados para um elemento de segurança. A Figura 2 ilustra como a emulação de cartão com base no host funciona:

Diagrama com leitor de NFC passando por um controlador de NFC para extrair informações da CPU
Figura 2. Emulação de cartão de NFC sem um elemento de segurança.

Cartões e protocolos de NFC compatíveis

Diagrama mostrando a pilha de protocolo HCE
Figura 3. Pilha de protocolo HCE do Android.

Os padrões de NFC oferecem suporte a muitos protocolos diferentes, e há diferentes tipos de cartão que podem ser emulados.

O Android 4.4 e versões mais recentes oferecem suporte a vários protocolos comuns no mercado atual. Muitos cartões por aproximação já são baseados nesses protocolos, como cartões de pagamento por aproximação. Esses protocolos também são compatíveis com muitos leitores de NFC no mercado atual, incluindo dispositivos Android NFC que funcionam como leitores (consulte a classe IsoDep). Isso permite que você crie e implante uma solução de NFC completa relacionada a HCE usando apenas dispositivos com tecnologia Android.

Especificamente, o Android 4.4 e versões mais recentes oferecem suporte à emulação de cartões baseados na especificação ISO-DEP do NFC-Forum (baseada em ISO/IEC 14443-4) e processam unidades de dados de protocolo de aplicativo (APDUs, na sigla em inglês) conforme definido na especificação ISO/IEC 7816-4. No Android, é obrigatório emular a ISO-DEP apenas sobre a tecnologia Nfc-A (ISO/IEC 14443-3 Tipo A). O suporte à tecnologia Nfc-B (ISO/IEC 14443-4 Tipo B) é opcional. A Figura 3 ilustra a sobreposição de todas essas especificações.

Serviços de HCE

A arquitetura HCE no Android é baseada em componentes Service do Android (conhecidos como serviços HCE). Uma das grandes vantagens de um serviço é a capacidade de execução em segundo plano sem nenhuma interface do usuário. Essa é uma opção natural para muitos aplicativos de HCE, como cartões de fidelidade ou transporte público, com os quais o usuário não precisa iniciar um app para usar. Em vez disso, tocar o dispositivo no leitor de NFC inicia o serviço correto, se ele ainda não estiver em execução, e executa a transação em segundo plano. Obviamente, você pode iniciar outra IU no serviço se necessário, como a de notificações do usuário.

Seleção de serviço

Quando o usuário toca um dispositivo em um leitor de NFC, o sistema Android precisa saber com qual serviço de HCE o leitor de NFC quer se comunicar. A especificação ISO/IEC 7816-4 define uma forma de selecionar apps, centralizada em um ID do aplicativo (AID). Um AID consiste em até 16 bytes. Se você estiver emulando cartões para uma infraestrutura de leitor de NFC, os AIDs desses leitores normalmente são bem conhecidos e registrados publicamente, por exemplo, os AIDs de redes de pagamento como Visa e MasterCard.

Se você quiser implantar uma nova infraestrutura de leitor para seu próprio app, registre seus próprios AIDs. O procedimento de registro de AIDs é definido na especificação ISO/IEC 7816-5. Recomendamos o registro de um AID conforme 7816-5 se você estiver implantando um aplicativo de HCE para Android, porque isso evita colisões com outros aplicativos.

Grupos de AID

Em alguns casos, um serviço de HCE pode precisar registrar vários AIDs e ser definido como o gerenciador padrão para todos os AIDs a fim de implementar um determinado app. Alguns AIDs no grupo que vão para outro serviço não são compatíveis.

Uma lista de AIDs que são mantidos juntos é chamada de grupo de AIDs. Para todos os AIDs em um grupo de AID, o Android garante um dos seguintes itens:

  • Todos os AIDs no grupo são roteados para esse serviço de HCE.
  • Nenhum AID no grupo é roteado para esse serviço de HCE, por exemplo, porque o usuário preferiu outro serviço que solicitou um ou mais AIDs no seu grupo também.

Em outras palavras, não há estado intermediário, em que alguns AIDs no grupo podem ser roteados para um serviço de HCE e outros para outro.

Categorias e grupos de AID

É possível associar cada grupo de AIDs a uma categoria. Isso permite que o Android agrupe serviços de HCE por categoria e, por sua vez, permite que o usuário defina padrões no nível da categoria em vez de no nível do AID. Evite mencionar AIDs em todas as partes do seu app voltadas ao usuário, porque eles não significam nada para o usuário comum.

O Android 4.4 e versões mais recentes oferecem suporte a duas categorias:

Implementar um serviço de HCE

Para emular um cartão de NFC usando a emulação de cartão com base no host, você precisa criar um componente Service que processe as transações de NFC.

Verificar o suporte para HCE

Seu app pode verificar se um dispositivo é compatível com HCE verificando o recurso FEATURE_NFC_HOST_CARD_EMULATION. Use a tag <uses-feature> no manifesto do aplicativo para declarar que ele usa o recurso HCE e se ele é necessário para o app funcionar ou não.

Implementação do serviço

O Android 4.4 e versões mais recentes oferecem uma classe Service de conveniência que pode ser usada como base para a implementação de um serviço de HCE: a classe HostApduService.

A primeira etapa é estender HostApduService, conforme mostrado no exemplo de código a seguir:

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 dois métodos abstratos que precisam ser substituídos e implementados. Um deles, processCommandApdu(), é chamado sempre que um leitor de NFC envia uma unidade de dados de protocolo de aplicativo (APDU, na sigla em inglês) para seu serviço. As APDUs são definidas na especificação ISO/IEC 7816-4. APDUs são os pacotes no nível do aplicativo trocados entre o leitor de NFC e seu serviço de HCE. Esse protocolo no nível do aplicativo é half-duplex: o leitor de NFC envia uma APDU de comando e aguarda que você envie uma APDU de resposta em retorno.

Como mencionado anteriormente, o Android usa o AID para determinar com qual serviço de HCE o leitor quer conversar. Normalmente, a primeira APDU que um leitor de NFC envia para seu dispositivo é uma APDU SELECT AID, que contém o AID com o que o leitor busca comunicação. O Android extrai esse AID da APDU, o resolve para um serviço de HCE e, em seguida, encaminha essa APDU para o serviço resolvido.

Você pode enviar uma APDU de resposta retornando os bytes da APDU de resposta de processCommandApdu(). Esse método é chamado na linha de execução principal do seu app, que não deve ser bloqueada. Se não for possível computar e retornar uma APDU de resposta imediatamente, retorne nulo. Você pode fazer o trabalho necessário em outra linha de execução e usar o método sendResponseApdu() definido na classe HostApduService para enviar a resposta quando terminar.

O Android continua encaminhando novas APDUs do leitor para seu serviço até que uma das seguintes situações ocorra:

  • O leitor de NFC envia outra APDU SELECT AID, que o SO resolve para um serviço diferente.
  • o link de NFC entre o leitor de NFC e seu dispositivo seja quebrado.

Em ambos os casos, a implementação onDeactivated() da classe é chamada com um argumento indicando qual dos dois ocorreu.

Se você estiver trabalhando com a infraestrutura de leitor atual, será necessário implementar o protocolo no nível do aplicativo esperado pelos leitores no serviço de HCE.

Se você estiver implantando uma nova infraestrutura de leitor que também controla, poderá definir seu próprio protocolo e sua sequência de APDU. Tente limitar a quantidade de APDUs e o tamanho dos dados a serem trocados. Isso garante que os usuários só precisem manter o dispositivo sobre o leitor de NFC por um curto período. Um limite superior razoável é cerca de 1 KB de dados, que geralmente podem ser trocados em 300 ms.

Declaração de manifesto de serviço e registro de AID

Você precisa declarar seu serviço no manifesto como de costume, mas também precisa adicionar partes adicionais à declaração de serviço:

  1. Para informar à plataforma que é um serviço de HCE que implementa a interface HostApduService, adicione um filtro de intent para a ação SERVICE_INTERFACE à declaração de serviço.

  2. Para informar à plataforma quais grupos de AIDs são solicitados por esse serviço, inclua uma tag SERVICE_META_DATA <meta-data> na declaração do serviço, apontando para um recurso XML com informações adicionais sobre o serviço de HCE.

  3. Defina o atributo android:exported como true e exija a permissão android.permission.BIND_NFC_SERVICE na declaração de serviço. O primeiro garante que o serviço possa ser vinculado por apps externos. O segundo reforça que apenas os apps externos que contêm a permissão android.permission.BIND_NFC_SERVICE podem se vincular ao serviço. Como android.permission.BIND_NFC_SERVICE é uma permissão do sistema, isso reforça efetivamente que somente o SO Android pode ser vinculado ao serviço.

Confira a seguir um exemplo de declaração de manifesto 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>

Essa tag de metadados aponta para um arquivo apduservice.xml. Confira abaixo um exemplo desse tipo de arquivo com uma única declaração de grupo de AIDs contendo dois AIDs proprietários:

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

A tag <host-apdu-service> precisa conter um atributo <android:description> que contenha uma descrição fácil de usar do serviço que pode ser exibido na interface do app. É possível usar o atributo requireDeviceUnlock para especificar que o dispositivo está desbloqueado antes de invocar esse serviço para processar APDUs.

O <host-apdu-service> precisa conter uma ou mais tags <aid-group>. Cada tag <aid-group> é necessária para fazer o seguinte:

  • Conter um atributo android:description que contenha uma descrição fácil de usar do grupo de AIDs, adequada para exibição na IU.
  • ter o atributo android:category definido para indicar a categoria à qual o grupo de AIDs pertence, como as constantes de string definidas por CATEGORY_PAYMENT ou CATEGORY_OTHER.
  • Conter uma ou mais tags <aid-filter>, cada uma contendo um único AID. Especifique o AID no formato hexadecimal e verifique se ele contém um número par de caracteres.

Seu app também precisa ter a permissão NFC para se registrar como um serviço de HCE.

Resolução de conflitos de AID

Vários componentes HostApduService podem ser instalados em um único dispositivo, e o mesmo AID pode ser registrado por mais de um serviço. O Android determina qual serviço invocar usando as seguintes etapas:

  1. Se o app de carteira padrão selecionado pelo usuário tiver registrado o AID, ele será invocado.
  2. Se o app de carteira padrão não tiver registrado o AID, o serviço que registrou o AID será invocado.
  3. Se mais de um serviço tiver registrado o AID, o Android vai perguntar ao usuário qual serviço invocar.

Preferência de serviço em primeiro plano

Os apps em primeiro plano podem invocar setPreferredService para especificar qual serviço de emulação de cartão deve ser preferido enquanto uma atividade específica está em primeiro plano. Essa preferência de app em primeiro plano substitui a resolução de conflitos de AID. Essa é uma prática recomendada quando o app prevê que o usuário pode usar a emulação de cartão NFC.

Android 13 e versões mais recentes

Para se ajustar melhor à lista de seleção de pagamento padrão na interface de configurações, ajuste a regra do banner para um ícone quadrado. O ideal é que ele seja idêntico ao design do ícone do iniciador do aplicativo. Esse ajuste cria mais consistência e um visual mais limpo.

Android 12 e versões anteriores

Defina o tamanho do banner do serviço como 260x96 dp e, em seguida, defina o tamanho do banner do serviço no arquivo XML de metadados adicionando o atributo android:apduServiceBanner à tag <host-apdu-service>, que aponta para o recurso drawable. Confira um exemplo:

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

Aplicativos da Carteira

O Android 15 e versões mais recentes incluem um papel padrão do app de carteira que o usuário pode selecionar em Configurações > Apps > Apps padrão. Isso define o app de carteira padrão a ser invocado quando um terminal de pagamento é tocado. O Android considera serviços de HCE que declararam um grupo de AIDs com a categoria de pagamento como apps de carteira.

Verificar se o app é o padrão

Os apps podem verificar se são o app de carteira padrão transmitindo RoleManager.ROLE_WALLET para RoleManager.isRoleHeld().

Se o app não for o padrão, solicite o papel padrão da carteira transmitindo RoleManager.ROLE_WALLET para RoleManager.createRequestRoleIntent().

Recursos obrigatórios para apps de carteira

Para oferecer uma experiência do usuário visualmente mais atraente, os apps de carteira de HCE precisam fornecer um banner de serviço.

Modo de observação

O Android 15 apresenta o recurso Observe Mode. Quando ativado, o modo de observação permite que o dispositivo observe loops de sondagem NFC e envie notificações sobre eles para os componentes HostApduService apropriados, para que eles possam se preparar para interagir com um determinado terminal NFC. Um HostApduService pode colocar o dispositivo no modo de observação transmitindo true para setObserveModeEnabled(). Isso instrui a pilha NFC a não permitir transações NFC e, em vez disso, observar passivamente os loops de polling.

Filtros de loop de pesquisa

É possível registrar filtros de loop de pesquisa para um HostApduService usando um dos seguintes métodos:

Quando um filtro de loop de pesquisa corresponde a frames de pesquisa não padrão, a pilha NFC encaminha esses frames para o HostApduService correspondente chamando o método processPollingFrames(). Isso permite que o serviço tome as medidas necessárias para garantir que o usuário esteja pronto para fazer transações e pretenda fazer isso, por exemplo, autenticando o usuário. Se um leitor de NFC estiver usando apenas frames padrão no loop de polling, a pilha NFC vai encaminhar esses frames de polling para o serviço de primeiro plano preferencial, se ele estiver em primeiro plano, ou para o detentor de função de carteira padrão, caso contrário.

As notificações de frame de pesquisa também incluem uma medição específica do fornecedor da intensidade do campo que pode ser recuperada chamando getVendorSpecificGain(). Os fornecedores podem fornecer medições usando a própria escala, desde que ela caiba em um único byte.

Responder a loops de pesquisa e sair do modo de observação

Quando o serviço estiver pronto para transações, ele poderá sair do modo de observação transmitindo false para setObserveModeEnabled(). A pilha NFC vai permitir que as transações continuem.

Os componentes HostApduService podem indicar que o modo de observação precisa ser ativado sempre que eles são o serviço de pagamento preferido. Para isso, defina shouldDefaultToObserveMode como true no manifesto ou chame CardEmulation.setShouldDefaultToObserveModeForService().

Os componentes HostApduService e OffHostApduService também podem indicar que os filtros de loop de polling que correspondem aos frames de loop de polling recebidos devem desativar automaticamente o modo de observação e permitir que as transações prossigam, definindo autoTransact como true na declaração PollingLoopFilter no manifesto.

Preferência de serviço em primeiro plano

Os apps em primeiro plano podem invocar setPreferredService para especificar qual serviço de emulação de cartão deve ser preferido enquanto uma atividade específica está em primeiro plano. Essa preferência do app em primeiro plano substitui o estado do modo de observação do dispositivo correspondente ao valor de shouldDefaultToObserveMode para um determinado serviço, que pode ser definido de uma das seguintes maneiras:

Tela desativada e comportamento da tela de bloqueio

O comportamento dos serviços HCE varia de acordo com a versão do Android em execução no dispositivo.

Android 15 e versões mais recentes

Se o app de carteira padrão ativar o modo de observação em um dispositivo compatível, ele vai substituir o comportamento de desbloqueio e de tela desligada, porque controla quando uma transação pode ser realizada. Alguns apps de carteira podem exigir que o dispositivo seja desbloqueado antes que uma transação seja concluída se o modo de observação não detectar um padrão de pesquisa identificável.

Recomendamos que os desenvolvedores trabalhem com os dispositivos de leitor para emitir padrões de loop de pesquisa identificáveis e se registrarem para processar esses padrões no app.

Android 12 e versões mais recentes

Em apps direcionados ao Android 12 (nível 31 da API) e versões mais recentes, é possível ativar pagamentos NFC com a tela do dispositivo desativada ao configurar requireDeviceScreenOn como false.

Android 10 e versões mais recentes

Dispositivos com o Android 10 (nível 29 da API) ou mais recente oferecem suporte ao NFC seguro. Enquanto a NFC segura estiver ativada, todos os emuladores de cartão (aplicativos host e fora do host) estarão indisponíveis quando a tela do dispositivo estiver desligada. Enquanto a NFC segura estiver desativada, os aplicativos fora do host estão disponíveis quando a tela do dispositivo está desligada. É possível verificar o suporte à NFC segura usando isSecureNfcSupported().

Em dispositivos com o Android 10 e versões mais recentes, a mesma funcionalidade para definir android:requireDeviceUnlock como true se aplica a dispositivos com o Android 9 e versões anteriores, mas apenas quando a NFC segura está desativada. Ou seja, se a NFC segura estiver ativada, os serviços de HCE não poderão funcionar na tela de bloqueio, independentemente da configuração de android:requireDeviceUnlock.

Android 9 e versões anteriores

Em dispositivos com o Android 9 (nível 28 da API) e versões anteriores, o controlador de NFC e o processador do aplicativo são desativados completamente quando a tela do dispositivo é desligada. Portanto, os serviços de HCE não funcionam quando a tela está desligada.

Além disso, no Android 9 e versões anteriores, os serviços de HCE podem funcionar na tela de bloqueio. No entanto, isso é controlado pelo atributo android:requireDeviceUnlock na tag <host-apdu-service> do serviço de HCE. Por padrão, o desbloqueio do dispositivo não é necessário, e seu serviço é invocado mesmo que o dispositivo esteja bloqueado.

Se você definir o atributo android:requireDeviceUnlock como true para o serviço de HCE, o Android vai pedir que o usuário desbloqueie o dispositivo quando o seguinte acontecer:

  • o usuário toca em um leitor de NFC.
  • o leitor de NFC seleciona um AID resolvido para seu serviço.

Após o desbloqueio, o Android mostra uma caixa de diálogo solicitando que o usuário toque novamente para concluir a transação. Isso é necessário porque o usuário pode ter movido o dispositivo para longe do leitor de NFC para desbloqueá-lo.

Coexistência com cartões de elemento de segurança

Esta seção é de interesse de desenvolvedores que implantaram um app que depende de um elemento de segurança para a emulação de cartão. A implementação de HCE do Android foi desenvolvida para funcionar em paralelo com outros métodos de implementação de emulação de cartão, incluindo o uso de elementos de segurança.

Essa coexistência se baseia em um princípio chamado roteamento de AID. O controlador de NFC mantém uma tabela de roteamento que consiste em uma lista (limitada) de regras de roteamento. Cada regra de roteamento contém um AID e um destino. O destino pode ser a CPU do host, em que os apps Android estão em execução, ou um elemento de segurança conectado.

Quando o leitor de NFC envia uma APDU com um SELECT AID, o controlador de NFC o analisa e verifica se os AIDs correspondem a qualquer AID na tabela de roteamento. Se ela corresponder, essa APDU e todas as APDUs após ela serão enviadas para o destino associado ao AID, até que outra APDU SELECT AID seja recebida ou que o link de NFC seja quebrado.

A Figura 4 ilustra essa arquitetura:

Diagrama com leitor de NFC se comunicando com um elemento de segurança e a CPU
Figura 4. Android operando com emulação de cartão de host e elemento de segurança.

O controlador de NFC normalmente também contém uma rota padrão para APDUs. Quando um AID não é encontrado na tabela de roteamento, a rota padrão é usada. Embora essa configuração possa ser diferente de dispositivo para dispositivo, os dispositivos Android precisam garantir que os AIDs registrados pelo seu app sejam roteados corretamente para o host.

Os aplicativos Android que implementam um serviço de HCE ou que usam um elemento de segurança não precisam se preocupar com a configuração da tabela de roteamento, que é processada automaticamente pelo Android. O Android só precisa saber quais AIDs podem ser gerenciados pelos serviços de HCE e quais podem ser gerenciados pelo elemento de segurança. A tabela de roteamento é configurada automaticamente com base nos serviços instalados e nos configurados como preferenciais pelo usuário.

A seção a seguir explica como declarar AIDs para aplicativos que usam um elemento de segurança para a emulação de cartões.

Registro do AID do elemento de segurança

Os apps que usam um elemento de segurança para emulação de cartão podem declarar um serviço fora do host no manifesto. A declaração de tal serviço é quase idêntica à declaração de um serviço de HCE. As exceções são as seguintes:

  • A ação usada no filtro de intent precisa ser definida como SERVICE_INTERFACE.
  • O atributo de nome de metadados precisa ser definido como SERVICE_META_DATA.
  • O arquivo XML de metadados precisa usar a tag raiz <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>
    

Confira a seguir um exemplo do arquivo apduservice.xml correspondente registrando dois AIDs:

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

O atributo android:requireDeviceUnlock não se aplica a serviços fora do host, porque a CPU do host não está envolvida na transação e, portanto, não pode impedir que o elemento de segurança execute transações quando o dispositivo está bloqueado.

O atributo android:apduServiceBanner é obrigatório para serviços fora do host que são apps de pagamento e para serem selecionáveis como um app de pagamento padrão.

Invocação de serviço fora do host

O Android nunca é iniciado ou vinculado a um serviço declarado como "fora do host", porque as transações reais são executadas pelo elemento de segurança e não pelo serviço do Android. A declaração de serviço só permite que os apps registrem AIDs presentes no elemento de segurança.

HCE e segurança

A arquitetura de HCE oferece uma proteção essencial: como seu serviço é protegido pela permissão de sistema BIND_NFC_SERVICE, somente o SO pode se vincular ao seu serviço e se comunicar com ele. Isso garante que qualquer APDU recebida seja, na verdade, uma APDU recebida pelo SO do controlador de NFC e que qualquer APDU enviada de volta retorne apenas ao SO, que, por sua vez, encaminhará diretamente as APDUs ao controlador de NFC.

A última preocupação é onde você recebe os dados que o app envia para o leitor de NFC. Isso é desacoplado intencionalmente no design de HCE. Não importa de onde os dados vêm, ele apenas garante que eles sejam transportados com segurança para o controlador de NFC e para o leitor de NFC.

Para armazenar e recuperar com segurança os dados que você quer enviar do serviço de HCE, é possível, por exemplo, confiar no sandbox do aplicativo para Android, que isola os dados do seu app de outros apps. Para mais detalhes sobre a segurança do Android, leia as Dicas de segurança.

Parâmetros de protocolo e detalhes

Esta seção é de interesse dos desenvolvedores que querem entender quais parâmetros de protocolo os dispositivos HCE usam durante as fases de anticolisão e ativação dos protocolos de NFC. Isso permite criar uma infraestrutura de leitor que é compatível com dispositivos Android HCE.

Anticolisão e ativação do protocolo Nfc-A (ISO/IEC 14443 tipo A)

Como parte da ativação do protocolo Nfc-A, vários frames são trocados.

Na primeira parte da troca, o dispositivo HCE apresenta o UID. Os dispositivos HCE precisam ter um UID aleatório. Isso significa que, a cada toque, o UID apresentado ao leitor é um UID gerado aleatoriamente. Por isso, os leitores de NFC não devem depender do UID de dispositivos HCE como uma forma de autenticação ou identificação.

Em seguida, o leitor de NFC pode selecionar o dispositivo HCE enviando um comando SEL_REQ. A resposta SEL_RES do dispositivo HCE tem pelo menos o sexto bit (0x20) definido, indicando que o dispositivo é compatível com ISO-DEP. Outros bits no SEL_RES também podem ser definidos, indicando, por exemplo, suporte para o protocolo NFC-DEP (p2p). Como outros bits podem ser definidos, os leitores que quiserem interagir com dispositivos HCE precisam verificar explicitamente o sexto bit e não comparar o SEL_RES completo com um valor de 0x20.

Ativação de ISO-DEP

Depois que o protocolo Nfc-A é ativado, o leitor de NFC inicia a ativação do protocolo ISO-DEP. Ele envia um comando de solicitação de resposta para seleção (RATS, na sigla em inglês). O controlador de NFC gera a resposta RATS, o ATS. O ATS não pode ser configurado pelos serviços de HCE. No entanto, as implementações de HCE precisam atender aos requisitos do Fórum de NFC para a resposta ATS. Assim, os leitores de NFC podem contar com esses parâmetros definidos de acordo com os requisitos do Fórum de NFC para qualquer dispositivo HCE.

A seção abaixo fornece mais detalhes sobre os bytes individuais da resposta ATS fornecida pelo controlador de NFC em um dispositivo HCE:

  • TL: comprimento da resposta ATS. Não pode indicar um comprimento com mais de 20 bytes.
  • T0: os bits 5, 6 e 7 precisam ser definidos em todos os dispositivos HCE, indicando que TA(1), TB(1) e TC(1) são incluídos na resposta ATS. Os bits 1 a 4 indicam o FSCI, codificando o tamanho máximo do frame. Em dispositivos HCE, o valor de FSCI precisa estar entre 0h e 8h.
  • T(A)1: define taxas de bits entre o leitor e o emulador, e se podem ser assimétricas. Não existem requisitos ou garantias de taxa de bits para dispositivos HCE.
  • T(B) 1: os bits 1 a 4 indicam o inteiro de tempo de ativação do frame de inicialização (SFGI, na sigla em inglês). Em dispositivos HCE, o SFGI precisa ser <= 8h. Os bits 5 a 8 indicam o inteiro de tempo de espera do frame (FWI, na sigla em inglês) e codificam o tempo de espera do frame (FWT, na sigla em inglês). Em dispositivos HCE, o FWI precisa ser <= 8h.
  • T(C) 1: o bit 5 indica suporte para "Recursos avançados do protocolo". Os dispositivos HCE podem ou não ser compatíveis com "Recursos avançados do protocolo". O bit 2 indica suporte para DID. Os dispositivos HCE podem ou não ser compatíveis com DID. O bit 1 indica suporte para NAD. Dispositivos HCE não devem ser compatíveis com NAD e definir o bit 1 como zero.
  • Bytes históricos: os dispositivos HCE podem retornar até 15 bytes históricos. Os leitores de NFC dispostos a interagir com os serviços de HCE não devem supor o conteúdo dos bytes históricos ou a presença deles.

Muitos dispositivos HCE provavelmente são compatíveis com os requisitos de protocolo especificados nas redes de pagamento unidas pelo EMVCo na especificação do "Protocolo de comunicação por aproximação". Especificamente, as seguintes:

  • O FSCI em T0 precisa estar entre 2h e 8h.
  • T(A)1 precisa ser definido como 0x80, indicando que apenas a taxa de bits de 106 kbit/s é aceita, e taxas de bits assimétricas entre leitor e emulador não são permitidas.
  • O FWI em T(B)1 precisa ser <= 7h.

Troca de dados da APDU

Como observado anteriormente, as implementações de HCE são compatíveis com apenas um único canal lógico. A tentativa de selecionar apps em canais lógicos diferentes não funciona em um dispositivo HCE.