De nombreux appareils Android dotés de la fonctionnalité NFC acceptent déjà l'émulation de carte NFC. Dans la plupart des cas, la carte est émulée par une puce électronique distincte dans l'appareil, appelée composant sécurisé. De nombreuses cartes SIM fournies par les opérateurs de téléphonie mobile contiennent également un composant sécurisé.
Android 4.4 et versions ultérieures proposent une autre méthode d'émulation de carte, appelée émulation de carte basée sur l'hôte, qui n'implique pas de composant sécurisé. Cela permet à n'importe quelle application Android d'émuler une carte et de communiquer directement avec le lecteur NFC. Cet article explique le fonctionnement de l'émulation de carte hébergée (HCE) sur Android et comment développer une application qui émule une carte NFC à l'aide de cette technique.
Émulation de carte avec un composant sécurisé
Lorsque l'émulation de carte NFC est fournie à l'aide d'un composant sécurisé, la carte à émuler est provisionnée dans le composant sécurisé de l'appareil via une application Android. Ensuite, lorsque l'utilisateur tient l'appareil au-dessus d'un terminal NFC, le contrôleur NFC de l'appareil achemine toutes les données du lecteur directement vers l'élément sécurisé. La figure 1 illustre ce concept:
L'élément sécurisé lui-même effectue la communication avec le terminal NFC, et aucune application Android n'est impliquée dans la transaction. Une fois la transaction terminée, une application Android peut interroger directement l'élément sécurisé pour connaître l'état de la transaction et en informer l'utilisateur.
Émulation de carte basée sur l'hôte
Lorsqu'une carte NFC est émulée à l'aide de l'émulation de carte basée sur l'hôte, les données sont acheminées directement vers le processeur hôte au lieu d'être acheminées vers un composant sécurisé. La figure 2 illustre le fonctionnement de l'émulation de carte basée sur l'hôte:
Cartes et protocoles NFC compatibles
Les normes NFC sont compatibles avec de nombreux protocoles différents, et vous pouvez émuler différents types de cartes.
Android 4.4 et les versions ultérieures sont compatibles avec plusieurs protocoles courants sur le marché. De nombreuses cartes sans contact existantes sont déjà basées sur ces protocoles, comme les cartes de paiement sans contact. Ces protocoles sont également compatibles avec de nombreux lecteurs NFC disponibles sur le marché, y compris les appareils NFC Android qui fonctionnent comme lecteurs (voir la classe IsoDep
). Vous pouvez ainsi créer et déployer une solution NFC de bout en bout autour de la technologie HCE en utilisant uniquement des appareils Android.
Plus précisément, Android 4.4 et versions ultérieures prennent en charge l'émulation de cartes basées sur la spécification ISO-DEP du NFC-Forum (basée sur ISO/CEI 14443-4) et le traitement des unités de données de protocole d'application (APDU) telles que définies dans la spécification ISO/CEI 7816-4. Android exige l'émulation ISO-DEP uniquement sur la technologie Nfc-A (ISO/CEI 14443-3 de type A). La prise en charge de la technologie Nfc-B (ISO/IEC 14443-4 de type B) est facultative. La figure 3 illustre la superposition de toutes ces spécifications.
Services HCE
L'architecture HCE d'Android est basée sur les composants Android Service
(appelés services HCE). L'un des principaux avantages d'un service est qu'il peut s'exécuter en arrière-plan sans interface utilisateur. Cette approche est adaptée à de nombreuses applications HCE, telles que les cartes de fidélité ou de transport en commun, que l'utilisateur ne devrait pas avoir besoin de lancer pour les utiliser. Au lieu de cela, le fait de placer l'appareil contre le lecteur NFC démarre le service approprié s'il n'est pas déjà en cours d'exécution et exécute la transaction en arrière-plan. Bien entendu, vous êtes libre de lancer une UI supplémentaire (telle que des notifications utilisateur) à partir de votre service lorsque cela est approprié.
Sélection de services
Lorsque l'utilisateur appuie sur un appareil contre un lecteur NFC, le système Android doit savoir avec quel service HCE le lecteur NFC souhaite communiquer. La spécification ISO/CEI 7816-4 définit un moyen de sélectionner des applications, axé sur un ID d'application (AID). Un AID peut contenir jusqu'à 16 octets. Si vous émulez des cartes pour une infrastructure de lecteur NFC existante, les AID que ces lecteurs recherchent sont généralement bien connus et enregistrés publiquement (par exemple, les AID des réseaux de paiement tels que Visa et MasterCard).
Si vous souhaitez déployer une nouvelle infrastructure de lecteur pour votre propre application, vous devez enregistrer vos propres AID. La procédure d'enregistrement des AID est définie dans la spécification ISO/CEI 7816-5. Nous vous recommandons d'enregistrer un AID conformément à la norme 7816-5 si vous déployez une application HCE pour Android, car cela évite les collisions avec d'autres applications.
Groupes AID
Dans certains cas, un service HCE peut être amené à enregistrer plusieurs AID et à être défini comme gestionnaire par défaut pour tous les AID afin d'implémenter une application spécifique. Certains AID du groupe redirigeant vers un autre service ne sont pas acceptés.
Une liste d'AID regroupés est appelée "groupe d'AID". Pour tous les AID d'un groupe d'AID, Android garantit l'une des options suivantes:
- Tous les AID du groupe sont acheminés vers ce service HCE.
- Aucun AID du groupe n'est acheminé vers ce service HCE (par exemple, parce que l'utilisateur a préféré un autre service qui a également demandé un ou plusieurs AID de votre groupe).
En d'autres termes, il n'existe pas d'état intermédiaire, où certains AID du groupe peuvent être acheminés vers un service HCE et d'autres vers un autre.
Groupes et catégories d'annonces in-app
Vous pouvez associer chaque groupe d'identifiants publicitaires à une catégorie. Cela permet à Android de regrouper les services HCE par catégorie, ce qui permet à l'utilisateur de définir des valeurs par défaut au niveau de la catégorie plutôt qu'au niveau de l'AID. Évitez de mentionner les AID dans les parties de votre application destinées aux utilisateurs, car ils n'ont aucune signification pour l'utilisateur moyen.
Android 4.4 et les versions ultérieures acceptent deux catégories:
CATEGORY_PAYMENT
(couvrant les applications de paiement standards du secteur)CATEGORY_OTHER
(pour toutes les autres applications HCE)
Implémenter un service HCE
Pour émuler une carte NFC à l'aide de l'émulation de carte hébergée, vous devez créer un composant Service
qui gère les transactions NFC.
Vérifier la compatibilité avec HCE
Votre application peut vérifier si un appareil est compatible avec la technologie HCE en vérifiant la fonctionnalité FEATURE_NFC_HOST_CARD_EMULATION
. Utilisez la balise <uses-feature>
dans le fichier manifeste de votre application pour déclarer qu'elle utilise la fonctionnalité HCE et si elle est requise pour son fonctionnement ou non.
Implémentation du service
Android 4.4 et versions ultérieures fournit une classe Service
pratique que vous pouvez utiliser comme base pour implémenter un service HCE: la classe HostApduService
.
La première étape consiste à étendre HostApduService
, comme indiqué dans l'exemple de code suivant:
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
déclare deux méthodes abstraites que vous devez remplacer et implémenter. L'un d'eux, processCommandApdu()
, est appelé chaque fois qu'un lecteur NFC envoie une unité de données de protocole d'application (APDU) à votre service. Les APDU sont définies dans la spécification ISO/CEI 7816-4. Les APDU sont les paquets au niveau de l'application échangés entre le lecteur NFC et votre service HCE. Ce protocole au niveau de l'application est en half-duplex: le lecteur NFC vous envoie une APDU de commande et attend que vous lui envoyiez une APDU de réponse en retour.
Comme indiqué précédemment, Android utilise l'AID pour déterminer le service HCE avec lequel le lecteur souhaite communiquer. En règle générale, le premier APDU qu'un lecteur NFC envoie à votre appareil est un APDU SELECT AID
. Cet APDU contient l'AID avec lequel le lecteur souhaite communiquer. Android extrait cet AID de l'APDU, le résout en service HCE, puis transfère cette APDU au service résolu.
Vous pouvez envoyer une APDU de réponse en renvoyant les octets de l'APDU de réponse à partir de processCommandApdu()
. Notez que cette méthode est appelée sur le thread principal de votre application, que vous ne devez pas bloquer. Si vous ne pouvez pas calculer et renvoyer immédiatement une APDU de réponse, renvoyez la valeur "null". Vous pouvez ensuite effectuer le travail nécessaire sur un autre thread et utiliser la méthode sendResponseApdu()
définie dans la classe HostApduService
pour envoyer la réponse lorsque vous avez terminé.
Android continue de transférer les nouveaux APDU du lecteur vers votre service, jusqu'à ce que l'un des événements suivants se produise:
- Le lecteur NFC envoie un autre APDU
SELECT AID
, que l'OS résout en un service différent. - La connexion NFC entre le lecteur NFC et votre appareil est interrompue.
Dans les deux cas, l'implémentation onDeactivated()
de votre classe est appelée avec un argument indiquant lequel des deux s'est produit.
Si vous utilisez une infrastructure de lecteur existante, vous devez implémenter le protocole existant au niveau de l'application que les lecteurs attendent dans votre service HCE.
Si vous déployez une nouvelle infrastructure de lecteur que vous contrôlez également, vous pouvez définir votre propre protocole et votre propre séquence APDU. Essayez de limiter le nombre d'APDU et la taille des données à échanger: vos utilisateurs n'auront ainsi qu'à maintenir leur appareil au-dessus du lecteur NFC pendant une courte période. Une limite supérieure raisonnable est d'environ 1 Ko de données, qui peuvent généralement être échangées en 300 ms.
Déclaration du fichier manifeste de service et enregistrement de l'AID
Vous devez déclarer votre service dans le fichier manifeste comme d'habitude, mais vous devez également ajouter des éléments supplémentaires à la déclaration de service:
Pour indiquer à la plate-forme qu'il s'agit d'un service HCE implémentant une interface
HostApduService
, ajoutez un filtre d'intent pour l'actionSERVICE_INTERFACE
à votre déclaration de service.Pour indiquer à la plate-forme les groupes d'AID demandés par ce service, incluez une balise
<meta-data>
SERVICE_META_DATA
dans la déclaration du service, pointant vers une ressource XML contenant des informations supplémentaires sur le service HCE.Définissez l'attribut
android:exported
surtrue
et exigez l'autorisationandroid.permission.BIND_NFC_SERVICE
dans votre déclaration de service. Le premier garantit que le service peut être lié par des applications externes. Ce dernier applique ensuite que seules les applications externes disposant de l'autorisationandroid.permission.BIND_NFC_SERVICE
peuvent s'associer à votre service. Étant donné queandroid.permission.BIND_NFC_SERVICE
est une autorisation système, cela garantit que seul l'OS Android peut se lier à votre service.
Voici un exemple de déclaration de fichier manifeste 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>
Cette balise de métadonnées pointe vers un fichier apduservice.xml
. Voici un exemple de fichier de ce type avec une seule déclaration de groupe d'AID contenant deux AID propriétaires:
<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 balise <host-apdu-service>
doit contenir un attribut <android:description>
qui contient une description conviviale du service que vous pouvez afficher dans l'interface utilisateur de l'application. Vous pouvez utiliser l'attribut requireDeviceUnlock
pour spécifier que l'appareil est déverrouillé avant d'appeler ce service pour gérer les APDU.
<host-apdu-service>
doit contenir une ou plusieurs balises <aid-group>
. Chaque balise <aid-group>
doit effectuer les opérations suivantes:
- Contient un attribut
android:description
contenant une description conviviale du groupe AID, adaptée à l'affichage dans l'UI. - Définissez son attribut
android:category
pour indiquer la catégorie à laquelle appartient le groupe d'AID, comme les constantes de chaîne définies parCATEGORY_PAYMENT
ouCATEGORY_OTHER
. - Contient une ou plusieurs balises
<aid-filter>
, chacune contenant un seul AID. Spécifiez l'AID au format hexadécimal et assurez-vous qu'il contient un nombre pair de caractères.
Votre application doit également disposer de l'autorisation NFC
pour s'enregistrer en tant que service HCE.
Résolution des conflits liés à l'AID
Plusieurs composants HostApduService
peuvent être installés sur un même appareil, et le même AID peut être enregistré par plusieurs services. Android détermine le service à appeler en procédant comme suit:
- Si l'application de portefeuille par défaut sélectionnée par l'utilisateur a enregistré l'AID, cette application est appelée.
- Si l'application de portefeuille par défaut n'a pas enregistré l'AID, le service qui a enregistré l'AID est appelé.
- Si plusieurs services ont enregistré l'AID, Android demande à l'utilisateur quel service appeler.
Préférence de service de premier plan
Les applications au premier plan peuvent appeler setPreferredService
pour spécifier le service d'émulation de carte à privilégier lorsqu'une activité spécifique est au premier plan. Cette préférence d'application de premier plan remplace la résolution des conflits AID. Cette pratique est recommandée lorsque l'application anticipe que l'utilisateur peut utiliser l'émulation de carte NFC.
Android 13 ou version ultérieure
Pour mieux s'adapter à la liste de sélection de paiement par défaut dans l'interface utilisateur des paramètres, définissez l'icône carrée comme exigence pour la bannière. Idéalement, elle doit être identique à la conception de l'icône du lanceur d'applications. Cet ajustement crée plus de cohérence et un aspect plus épuré.
Android 12 ou version antérieure
Définissez la taille de la bannière de service sur 260x96 dp, puis définissez la taille de la bannière de service dans votre fichier XML de métadonnées en ajoutant l'attribut android:apduServiceBanner
à la balise <host-apdu-service>
, qui pointe vers la ressource drawable. Voici un exemple:
<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>
Applications Wallet
Android 15 et les versions ultérieures incluent un rôle d'application de portefeuille par défaut que l'utilisateur peut sélectionner en accédant à Settings > Apps > Default Apps (Paramètres > Applications > Applications par défaut). Cela définit l'application de portefeuille par défaut à appeler lorsqu'un terminal de paiement est utilisé. Android considère les services HCE ayant déclaré un groupe d'AID avec la catégorie de paiement comme des applications de portefeuille.
Vérifier si votre application est l'application de portefeuille par défaut
Les applications peuvent vérifier si elles sont l'application de portefeuille par défaut en transmettant RoleManager.ROLE_WALLET
à RoleManager.isRoleHeld()
.
Si votre application n'est pas définie par défaut, vous pouvez demander le rôle de portefeuille par défaut en transmettant RoleManager.ROLE_WALLET
à RoleManager.createRequestRoleIntent()
.
Éléments requis pour les applications de portefeuille
Pour offrir une expérience utilisateur plus attrayante visuellement, les applications de portefeuille HCE doivent fournir une bannière de service.
Mode d'observation
Android 15 introduit la fonctionnalité Mode observation. Lorsqu'il est activé, le mode d'observation permet à l'appareil d'observer les boucles de sondage NFC et d'envoyer des notifications à leur sujet aux composants HostApduService
appropriés afin qu'ils puissent se préparer à interagir avec un terminal NFC donné. Un HostApduService
peut mettre l'appareil en mode Observation en transmettant true
à setObserveModeEnabled()
.
Cela indique à la pile NFC de ne pas autoriser les transactions NFC et d'observer passivement les boucles de sondage.
Filtres de boucle d'interrogation
Vous pouvez enregistrer des filtres de boucle de sondage pour un HostApduService
à l'aide de l'une des méthodes suivantes:
registerPollingLoopFilterForService()
pour les filtres qui doivent correspondre exactement à un frame de sondage.registerPollingLoopPatternFilterForService()
pour les filtres qui correspondent à une expression régulière avec des trames de sondage.
Lorsqu'un filtre de boucle de sondage correspond à des trames de sondage non standard, la pile NFC achemine ces trames de sondage vers le HostApduService
correspondant en appelant sa méthode processPollingFrames()
. Cela permet au service de prendre toutes les mesures nécessaires pour s'assurer que l'utilisateur est prêt à effectuer une transaction et qu'il a l'intention de le faire (par exemple, en l'authentifiant). Si un lecteur NFC n'utilise que des trames standards dans sa boucle de sondage, la pile NFC achemine ces trames de sondage vers le service de premier plan préféré si ce service est au premier plan, ou vers le titulaire du rôle de portefeuille par défaut dans le cas contraire.
Les notifications de trame de sondage incluent également une mesure de l'intensité du champ spécifique au fournisseur que vous pouvez récupérer en appelant getVendorSpecificGain()
.
Les fournisseurs peuvent fournir des mesures à l'aide de leur propre échelle, à condition qu'elle tienne dans un seul octet.
Répondre aux boucles de sondage et quitter le mode d'observation
Lorsque le service est prêt à effectuer une transaction, il peut quitter le mode d'observation en transmettant false
à setObserveModeEnabled()
. La pile NFC autorisera alors les transactions.
Les composants HostApduService
peuvent indiquer que le mode d'observation doit être activé chaque fois qu'ils sont le service de paiement préféré en définissant shouldDefaultToObserveMode
sur true
dans le fichier manifeste ou en appelant CardEmulation.setShouldDefaultToObserveModeForService()
.
Les composants HostApduService
et OffHostApduService
peuvent également indiquer que les filtres de boucle de sondage correspondant aux trames de boucle de sondage reçues doivent désactiver automatiquement le mode d'observation et autoriser les transactions à se poursuivre en définissant autoTransact
sur true
dans la déclaration PollingLoopFilter
du fichier manifeste.
Préférence de service de premier plan
Les applications au premier plan peuvent appeler setPreferredService
pour spécifier le service d'émulation de carte à privilégier lorsqu'une activité spécifique est au premier plan. Cette préférence d'application de premier plan remplace l'état du mode d'observation de l'appareil correspondant à la valeur de shouldDefaultToObserveMode
pour un service donné, qui peut être défini de l'une des manières suivantes:
- Définir l'état de
shouldDefaultToObserveMode
dans le fichier manifeste pour ce service. - Appel de
CardEmulation.setShouldDefaultToObserveModeForService()
avec le service et l'état correspondants.
Comportement de l'écran éteint et de l'écran de verrouillage
Le comportement des services HCE varie en fonction de la version d'Android exécutée sur l'appareil.
Android 15 ou version ultérieure
Si l'application Wallet par défaut active le mode d'observation sur un appareil compatible, cette application remplace le comportement de déverrouillage et de mise hors service de l'écran, car elle contrôle le moment où une transaction peut être effectuée. Certaines applications de portefeuille peuvent nécessiter le déverrouillage de l'appareil avant qu'une transaction puisse être effectuée si le mode d'observation n'a pas détecté de modèle de boucle d'interrogation identifiable.
Les développeurs sont encouragés à travailler avec leurs lecteurs pour émettre des modèles de boucles de sondage identifiables et à s'inscrire pour gérer ces modèles à partir de leur application.
Android 12 ou version ultérieure
Dans les applications qui ciblent Android 12 (niveau d'API 31) ou version ultérieure, vous pouvez activer les paiements NFC sans que l'écran de l'appareil ne soit allumé en définissant requireDeviceScreenOn
sur false
.
Android 10 ou version ultérieure
Les appareils équipés d'Android 10 (niveau d'API 29) ou version ultérieure sont compatibles avec la technologie NFC sécurisée. Lorsque le NFC sécurisé est activé, tous les émulateurs de carte (applications hôtes et applications hors hôte) sont indisponibles lorsque l'écran de l'appareil est éteint. Lorsque le NFC sécurisé est désactivé, les applications hors hôte sont disponibles lorsque l'écran de l'appareil est éteint. Vous pouvez vérifier la compatibilité avec le NFC sécurisé à l'aide de isSecureNfcSupported()
.
Sur les appareils équipés d'Android 10 ou version ultérieure, la même fonctionnalité pour définir android:requireDeviceUnlock
sur true
s'applique que pour les appareils équipés d'Android 9 ou version antérieure, mais uniquement lorsque la technologie NFC sécurisée est désactivée. Autrement dit, si la technologie NFC sécurisée est activée, les services HCE ne peuvent pas fonctionner depuis l'écran de verrouillage, quel que soit le paramètre de android:requireDeviceUnlock
.
Android 9 ou version antérieure
Sur les appareils équipés d'Android 9 (niveau d'API 28) ou d'une version antérieure, le contrôleur NFC et le processeur d'application sont complètement désactivés lorsque l'écran de l'appareil est éteint. Les services HCE ne fonctionnent donc pas lorsque l'écran est éteint.
De plus, sous Android 9 ou version antérieure, les services HCE peuvent fonctionner depuis l'écran de verrouillage.
Toutefois, cela est contrôlé par l'attribut android:requireDeviceUnlock
dans la balise <host-apdu-service>
de votre service HCE. Par défaut, le déverrouillage de l'appareil n'est pas requis, et votre service est appelé même si l'appareil est verrouillé.
Si vous définissez l'attribut android:requireDeviceUnlock
sur true
pour votre service HCE, Android invite l'utilisateur à déverrouiller l'appareil lorsque les événements suivants se produisent:
- l'utilisateur appuie sur un lecteur NFC.
- Le lecteur NFC sélectionne un AID qui est résolu en votre service.
Après le déverrouillage, Android affiche une boîte de dialogue invitant l'utilisateur à appuyer à nouveau pour finaliser la transaction. Cela est nécessaire, car l'utilisateur peut avoir éloigné l'appareil du lecteur NFC pour le déverrouiller.
Coexistence avec les cartes dotées d'un composant sécurisé
Cette section s'adresse aux développeurs qui ont déployé une application qui s'appuie sur un composant sécurisé pour l'émulation de carte. L'implémentation HCE d'Android est conçue pour fonctionner en parallèle avec d'autres méthodes d'implémentation de l'émulation de carte, y compris l'utilisation de composants sécurisés.
Cette coexistence repose sur un principe appelé routage AID. Le contrôleur NFC conserve une table de routage composée d'une liste (finie) de règles de routage. Chaque règle de routage contient un AID et une destination. La destination peut être le processeur hôte, où les applications Android s'exécutent, ou un élément sécurisé connecté.
Lorsque le lecteur NFC envoie un APDU avec un SELECT AID
, le contrôleur NFC l'analyse et vérifie si les AID correspondent à un AID de sa table de routage. Si elle correspond, cette APDU et toutes les APDU qui la suivent sont envoyées à la destination associée à l'AID, jusqu'à ce qu'une autre APDU SELECT AID
soit reçue ou que la liaison NFC soit interrompue.
La figure 4 illustre cette architecture:
Le contrôleur NFC contient généralement également une route par défaut pour les APDU. Lorsqu'un AID n'est pas trouvé dans le tableau de routage, la route par défaut est utilisée. Bien que ce paramètre puisse varier d'un appareil à l'autre, les appareils Android doivent s'assurer que les AID enregistrés par votre application sont correctement acheminés vers l'hôte.
Les applications Android qui implémentent un service HCE ou qui utilisent un composant sécurisé n'ont pas à se soucier de configurer la table de routage. Android s'en occupe automatiquement. Android doit simplement savoir quels AID peuvent être gérés par les services HCE et lesquels peuvent être gérés par le composant sécurisé. La table de routage est configurée automatiquement en fonction des services installés et de ceux que l'utilisateur a configurés comme étant de préférence.
La section suivante explique comment déclarer des AID pour les applications qui utilisent un composant sécurisé pour l'émulation de carte.
Enregistrement de l'AID du composant sécurisé
Les applications qui utilisent un composant sécurisé pour l'émulation de carte peuvent déclarer un service hors hôte dans leur fichier manifeste. La déclaration d'un tel service est presque identique à celle d'un service HCE. Les exceptions sont les suivantes:
- L'action utilisée dans le filtre d'intent doit être définie sur
SERVICE_INTERFACE
. - L'attribut de nom des métadonnées doit être défini sur
SERVICE_META_DATA
. Le fichier XML de métadonnées doit utiliser la balise racine
<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>
Voici un exemple de fichier apduservice.xml
correspondant qui enregistre deux 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>
L'attribut android:requireDeviceUnlock
ne s'applique pas aux services hors hôte, car le processeur hôte n'est pas impliqué dans la transaction et ne peut donc pas empêcher l'élément sécurisé d'exécuter des transactions lorsque l'appareil est verrouillé.
L'attribut android:apduServiceBanner
est obligatoire pour les services hors hôte qui sont des applications de paiement et pour pouvoir être sélectionnés comme application de paiement par défaut.
Appel de service hors hôte
Android ne démarre ni ne se lie jamais à un service déclaré comme "hors hôte", car les transactions réelles sont exécutées par l'élément sécurisé et non par le service Android. La déclaration de service permet simplement aux applications d'enregistrer les AID présents sur le composant sécurisé.
HCE et sécurité
L'architecture HCE fournit un élément de sécurité essentiel: comme votre service est protégé par l'autorisation système BIND_NFC_SERVICE
, seul l'OS peut se lier à votre service et communiquer avec lui.
Cela garantit que toute APDU que vous recevez est en fait une APDU reçue par l'OS à partir du contrôleur NFC, et que toute APDU que vous renvoyez ne va qu'à l'OS, qui à son tour transfère directement les APDU au contrôleur NFC.
Le dernier problème concerne l'origine des données que votre application envoie au lecteur NFC. Cette approche est intentionnellement dissociée dans la conception HCE. Elle ne se soucie pas de l'origine des données, mais s'assure simplement qu'elles sont transportées de manière sécurisée vers le contrôleur NFC et vers le lecteur NFC.
Pour stocker et récupérer de manière sécurisée les données que vous souhaitez envoyer à partir de votre service HCE, vous pouvez, par exemple, vous appuyer sur le bac à sable de l'application Android, qui isole les données de votre application des autres applications. Pour en savoir plus sur la sécurité Android, consultez les conseils de sécurité.
Paramètres et détails du protocole
Cette section intéressera les développeurs qui souhaitent comprendre quels paramètres de protocole les appareils HCE utilisent pendant les phases d'anticollision et d'activation des protocoles NFC. Cela permet de créer une infrastructure de lecteur compatible avec les appareils Android HCE.
Anticollision et activation du protocole NFC-A (ISO/IEC 14443 type A)
Lors de l'activation du protocole Nfc-A, plusieurs trames sont échangées.
Dans la première partie de l'échange, l'appareil HCE présente son UID. On suppose que les appareils HCE disposent d'un UID aléatoire. Cela signifie que, à chaque appui, l'UID présenté au lecteur est un UID généré de manière aléatoire. Par conséquent, les lecteurs NFC ne doivent pas dépendre de l'UID des appareils HCE comme forme d'authentification ou d'identification.
Le lecteur NFC peut ensuite sélectionner l'appareil HCE en envoyant une commande SEL_REQ
. La réponse SEL_RES
de l'appareil HCE comporte au moins le 6e bit (0x20) défini, ce qui indique que l'appareil est compatible avec ISO-DEP. Notez que d'autres bits de l'SEL_RES
peuvent également être définis, ce qui indique, par exemple, la compatibilité avec le protocole NFC-DEP (p2p). Étant donné que d'autres bits peuvent être définis, les lecteurs qui souhaitent interagir avec des appareils HCE doivent vérifier explicitement le 6e bit uniquement et ne pas comparer l'SEL_RES
complète à une valeur de 0x20.
Activation d'ISO-DEP
Une fois le protocole Nfc-A activé, le lecteur NFC lance l'activation du protocole ISO-DEP. Il envoie une commande RATS (Request for Answer To Select). Le contrôleur NFC génère la réponse RATS, l'ATS. L'ATS n'est pas configurable par les services HCE. Toutefois, les implémentations HCE doivent respecter les exigences du Forum NFC pour la réponse ATS. Les lecteurs NFC peuvent donc compter sur la configuration de ces paramètres conformément aux exigences du Forum NFC pour tout appareil HCE.
La section ci-dessous fournit plus d'informations sur les octets individuels de la réponse ATS fournie par le contrôleur NFC sur un appareil HCE:
- TL: longueur de la réponse de l'ATS. Ne doit pas indiquer une longueur supérieure à 20 octets.
- T0: les bits 5, 6 et 7 doivent être définis sur tous les appareils HCE, ce qui indique que TA(1), TB(1) et TC(1) sont inclus dans la réponse ATS. Les bits 1 à 4 indiquent le FSCI, qui code la taille maximale des images. Sur les appareils HCE, la valeur de FSCI doit être comprise entre 0h et 8h.
- T(A)1: définit les débits entre le lecteur et l'émulateur, et s'ils peuvent être asymétriques. Aucune exigence ni garantie de débit ne s'applique aux appareils HCE.
- T(B)1: les bits 1 à 4 indiquent l'entier SFGI (Start-up Frame Guard time). Sur les appareils HCE, la durée de validité de la clé doit être inférieure ou égale à huit heures. Les bits 5 à 8 indiquent l'entier de temps d'attente de trame (FWI) et codent le temps d'attente de trame (FWT). Sur les appareils HCE, la FWI doit être inférieure ou égale à 8 heures.
- T(C)1: le bit 5 indique la prise en charge des "fonctionnalités avancées du protocole". Les appareils HCE peuvent ou non être compatibles avec les "fonctionnalités avancées du protocole". Le bit 2 indique la prise en charge des DID. Les appareils HCE peuvent ou non être compatibles avec les DID. Le bit 1 indique la prise en charge de NAD. Les appareils HCE ne doivent pas prendre en charge NAD et définir le bit 1 sur zéro.
- Octets d'historique: les appareils HCE peuvent renvoyer jusqu'à 15 octets d'historique. Les lecteurs NFC souhaitant interagir avec les services HCE ne doivent faire aucune hypothèse sur le contenu des octets historiques ni sur leur présence.
Notez que de nombreux appareils HCE sont probablement conformes aux exigences de protocole que les réseaux de paiement réunis dans EMVCo ont spécifiées dans leur spécification "Protocole de communication sans contact". En particulier :
- La valeur FSCI en T0 doit être comprise entre 2 et 8 heures.
- T(A)1 doit être défini sur 0x80, ce qui indique que seul le débit de 106 kbit/s est pris en charge et que les débits asymétriques entre le lecteur et l'émulateur ne sont pas pris en charge.
- La FWI dans T(B)1 doit être inférieure ou égale à 7 heures.
Échange de données APDU
Comme indiqué précédemment, les implémentations HCE ne prennent en charge qu'un seul canal logique. La tentative de sélection d'applications sur différents canaux logiques ne fonctionne pas sur un appareil HCE.