NFC 기능을 제공하는 많은 Android 지원 기기에서 이미 NFC 카드 에뮬레이션을 지원하고 있습니다. 대체로 카드는 보안 요소라고 하는 기기의 별도 칩에 의해 에뮬레이션됩니다. 또한 무선 이동통신사에서 제공하는 여러 SIM 카드에도 보안 요소가 포함되어 있습니다.
Android 4.4에는 보안 요소가 포함되지 않은 추가적인 카드 에뮬레이션 방법인 호스트 기반 카드 에뮬레이션이 도입되었습니다. 이 에뮬레이션 방법을 통해 Android 애플리케이션에서 카드를 에뮬레이션하고 NFC 리더와 직접 통신할 수 있습니다. 이 문서에서는 Android에서 호스트 기반 카드 에뮬레이션(HCE)이 작동하는 방식과 이 기법을 사용하여 NFC 카드를 에뮬레이션하는 앱을 개발하는 방법을 설명합니다.
보안 요소가 있는 카드 에뮬레이션
보안 요소를 사용하여 NFC 카드 에뮬레이션을 제공할 때 에뮬레이션할 카드는 Android 애플리케이션을 통해 기기의 보안 요소에 프로비저닝됩니다. 이후에 사용자가 기기를 NFC 단말기에 올려놓으면 기기의 NFC 컨트롤러가 리더의 모든 데이터를 보안 요소로 직접 라우팅합니다. 그림 1은 이 개념을 보여줍니다.

그림 1. 보안 요소가 있는 NFC 카드 에뮬레이션
보안 요소가 직접 NFC 단말기와의 통신을 실행하며 Android 애플리케이션이 트랜잭션에 전혀 관여하지 않습니다. 트랜잭션이 완료된 후 Android 애플리케이션이 트랜잭션 상태를 보안 요소에 직접 쿼리하여 사용자에게 알릴 수 있습니다.
호스트 기반 카드 에뮬레이션
호스트 기반 카드 에뮬레이션을 사용하여 NFC 카드를 에뮬레이션할 때는 NFC 프로토콜 프레임을 보안 요소로 라우팅하는 대신 Android 애플리케이션이 실행되고 있는 호스트 CPU로 데이터를 직접 라우팅합니다. 그림 2는 호스트 기반 카드 에뮬레이션의 작동 방식을 보여줍니다.

그림 2. 보안 요소가 없는 NFC 카드 에뮬레이션
지원되는 NFC 카드 및 프로토콜

그림 3. Android의 HCE 프로토콜 스택
NFC 표준은 여러 다양한 프로토콜을 지원합니다. 그리고 에뮬레이션할 수 있는 다양한 카드 유형이 있습니다.
Android 4.4는 오늘날 시장에서 일반적으로 사용되는 몇 가지 프로토콜을 지원합니다. 미접촉 결제 카드와 같은 기존의 많은 미접촉 카드는 이미 이러한 프로토콜을 기반으로 하고 있습니다. 또한 오늘날 리더로 직접 작동하는 Android NFC 기기(IsoDep
클래스 참조)를 포함하여 시장의 많은 NFC 리더도 이러한 프로토콜을 지원합니다.
덕분에 Android 지원 기기만 사용하여 HCE를 중심으로로 한 엔드 투 엔드 NFC 솔루션을 구축하고 배포할 수 있습니다.
특히 Android 4.4는 NFC-Forum ISO-DEP 사양(ISO/IEC 14443-4 기반)을 기반으로 하는 카드 에뮬레이션 및 ISO/IEC 7816-4 사양에 정의된 프로세스 APDU(Application Protocol Data Unit)를 지원합니다. Android는 Nfc-A(ISO/IEC 14443-3 Type A) 기술을 기반으로 ISO-DEP를 에뮬레이션해야 합니다. Nfc-B(ISO/IEC 14443-4 Type B) 기술 지원은 선택사항입니다. 이러한 모든 사양의 레이어링은 그림 3에 나와 있습니다.
HCE 서비스
Android의 HCE 아키텍처는 Android Service
구성요소('HCE 서비스'로 알려져 있음)를 기반으로 합니다.
서비스의 주요 이점 중 하나는 사용자 인터페이스 없이 백그라운드에서 실행할 수 있다는 것입니다. 따라서 충성도 또는 대중교통 카드와 같은 많은 HCE 애플리케이션에 적합하며 사용자가 서비스를 사용하기 위해 앱을 시작할 필요가 없습니다.
대신 NFC 리더에 기기를 탭하면 적절한 서비스가 시작되고(아직 실행되지 않았다면) 백그라운드에서 트랜잭션이 실행됩니다. 물론 상황에 따라 필요하다면 언제든지 서비스에서 추가 UI(예: 사용자 알림)를 시작할 수 있습니다.
서비스 선택
사용자가 기기를 NFC 리더에 탭할 때 Android 시스템은 NFC 리더가 실제로 통신하려는 HCE 서비스를 인식하고 있어야 합니다. 이때 ISO/IEC 7816-4 사양이 필요합니다. 이 사양은 애플리케이션 ID(AID)를 중심으로 애플리케이션을 선택하는 방법을 정의합니다. AID는 최대 16바이트로 구성됩니다. 기존 NFC 리더 인프라에 맞춰 카드를 에뮬레이션한다면 이 리더가 찾고 있는 AID는 일반적으로 잘 알려져 있고 공개적으로 등록된 것입니다(예: Visa 및 MasterCard와 같은 결제 네트워크의 AID).
자체 애플리케이션을 위해 새로운 리더 인프라를 배포하려면 고유한 AID를 등록해야 합니다. AID 등록 절차는 ISO/IEC 7816-5 사양에 정의되어 있습니다. Android용 HCE 애플리케이션을 배포하려면 7816-5에 따라 AID를 등록하는 것이 좋습니다. 그러면 다른 애플리케이션과의 충돌을 피할 수 있기 때문입니다.
AID 그룹
HCE 서비스가 특정 애플리케이션을 구현하기 위해 여러 AID를 등록해야 하는 사례도 있으며 HCE 서비스는 자신이 이러한 모든 AID의 기본 핸들러인지 확인해야 합니다(그룹의 일부 AID가 다른 서비스로 이동하는 상황과 반대).
AID 그룹은 OS에서 한 그룹에 함께 속하는 것으로 간주해야 하는 AID 목록입니다. AID 그룹의 모든 AID와 관련하여 Android는 다음 중 하나를 보장합니다.
- 그룹의 모든 AID가 이 HCE 서비스로 라우팅됩니다.
- 그룹의 AID가 이 HCE 서비스로 라우팅되지 않습니다(예를 들어 사용자가 그룹 내 하나 이상의 AID를 요청한 다른 서비스도 원했기 때문에).
즉, 그룹의 일부 AID는 한 HCE 서비스로 라우팅되고 일부는 다른 HCE 서비스로 라우팅될 수 있는 중간 상태는 없습니다.
AID 그룹 및 카테고리
각 AID 그룹은 카테고리와 연결될 수 있습니다. 이러한 연결을 통해 Android는 HCE 서비스를 카테고리별로 함께 그룹화할 수 있으며 결과적으로 사용자가 AID 수준 대신 카테고리 수준에서 기본값을 설정할 수 있습니다. 일반적으로 사용자에게 표시되는 애플리케이션 요소에서는 AID를 언급하지 않아야 합니다. AID는 일반 사용자에게 아무 의미가 없습니다.
Android 4.4는 두 가지 카테고리인 CATEGORY_PAYMENT
(업계 표준 결제 앱 포괄 카테고리)와 CATEGORY_OTHER
(다른 모든 HCE 앱 포괄 카테고리)를 지원합니다.
참고: 특정 시점에는 시스템에서 CATEGORY_PAYMENT
카테고리의 AID 그룹을 하나만 사용 설정할 수 있습니다. 일반적으로 이 그룹은 주요 신용카드 결제 프로토콜을 인식하고 모든 판매자에서 작동할 수 있는 앱입니다.
한 판매자에서만 작동하는 폐쇄 루프 결제 앱(예: 가치 저장 카드[SVC])에는 CATEGORY_OTHER
를 사용해야 합니다. 이 카테고리의 AID 그룹은 항상 활성 상태일 수 있으며 필요 시 AID를 선택하는 동안 NFC 리더에 의해 우선순위를 부여받을 수 있습니다.
HCE 서비스 구현
호스트 기반 카드 에뮬레이션을 사용하여 NFC 카드를 에뮬레이션하려면 NFC 트랜잭션을 처리하는 Service
구성요소를 생성해야 합니다.
HCE 지원 확인
애플리케이션은 FEATURE_NFC_HOST_CARD_EMULATION
기능을 확인하여 기기가 HCE를 지원하는지 여부를 알 수 있습니다. 개발자는 애플리케이션의 manifest에서 <uses-feature>
태그를 사용하여 앱이 HCE 기능을 사용하며 앱이 작동하는 데 HCE 기능이 필요한지 여부를 선언해야 합니다.
서비스 구현
Android 4.4에는 HCE 서비스 구현을 위한 기반으로 사용할 수 있는 편의 Service
클래스인 HostApduService
클래스가 제공됩니다.
따라서 첫 번째 단계는 HostApduService
를 확장하는 것입니다.
Kotlin
class MyHostApduService : HostApduService() { override fun processCommandApdu(commandApdu: ByteArray, extras: Bundle?): ByteArray { ... } override fun onDeactivated(reason: Int) { ... } }
자바
public class MyHostApduService extends HostApduService { @Override public byte[] processCommandApdu(byte[] apdu, Bundle extras) { ... } @Override public void onDeactivated(int reason) { ... } }
HostApduService
는 재정의하고 구현해야 하는 두 가지 추상 메서드를 선언합니다.
processCommandApdu()
는 NFC 리더가 APDU(Application Protocol Data Unit)를 서비스로 전송할 때마다 호출됩니다. APDU는 ISO/IEC 7816-4 사양에도 정의되어 있습니다. APDU는 NFC 리더와 HCE 서비스 간에 교환되는 애플리케이션 수준의 패킷입니다. 이 애플리케이션 수준 프로토콜은 반이중입니다. 즉, NFC 리더는 APDU 명령을 전송하고 반응으로 응답 APDU를 수신할 때까지 기다립니다.
참고: 또한 ISO/IEC 7816-4 사양은 여러 논리 채널의 개념도 정의합니다. 이러한 개념에서는 별도의 논리 채널에 여러 개의 병렬 APDU 교환을 포함할 수 있습니다. 그러나 Android의 HCE 구현은 단일 논리 채널만 지원하므로 APDU의 단일 스레드 교환만 있습니다.
앞서 언급했듯이 Android는 AID를 사용하여 리더가 통신하려는 HCE 서비스를 결정합니다. 일반적으로 NFC 리더가 기기에 전송하는 첫 번째 APDU는 'SELECT AID' APDU입니다. 이 APDU에는 리더가 통신하려는 AID가 포함되어 있습니다. Android는 APDU에서 AID를 추출하여 HCE 서비스로 확인한 후 확인된 서비스에 이 APDU를 전달합니다.
processCommandApdu()
의 응답 APDU 바이트를 반환하여 응답 APDU를 전송할 수 있습니다.
이 메서드는 애플리케이션의 기본 스레드에서 호출되며 차단되어서는 안 됩니다. 따라서 응답 APDU를 즉시 계산하여 반환할 수 없다면 null을 반환합니다. 그런 다음 다른 스레드에서 필요한 작업을 실행하고 완료 시 HostApduService
클래스에 정의된 sendResponseApdu()
메서드를 사용하여 응답을 전송할 수 있습니다.
다음 중 한 가지 상황이 발생할 때까지 Android는 새로운 APDU를 리더에서 서비스로 계속 전달합니다.
- NFC 리더가 다른 'SELECT AID' APDU를 전송하고 OS가 이를 다른 서비스로 확인합니다.
- NFC 리더와 기기 간의 NFC 링크가 끊어집니다.
두 가지 상황 모두에서 클래스의 onDeactivated()
구현이 두 가지 중 어느 것이 발생했는지 나타내는 인수와 함께 호출됩니다.
기존 리더 인프라에서 작업한다면 리더가 HCE 서비스에서 예상하는 기존 애플리케이션 수준 프로토콜을 구현해야 합니다.
직접 제어하는 새로운 리더 인프라도 배포한다면 고유한 프로토콜 및 APDU 시퀀스를 정의할 수 있습니다. 보통 APDU의 양 및 교환해야 하는 데이터의 크기를 제한합니다. 이렇게 하면 사용자가 기기를 NFC 리더에 잠깐 동안만 올려놓고 기다리면 됩니다. 합리적인 상한은 약 1KB의 데이터입니다. 이 크기의 데이터는 일반적으로 300ms 이내에 교환할 수 있습니다.
서비스 manifest 선언 및 AID 등록
서비스는 항상 manifest에서 선언해야 하지만 일부 추가 부분도 서비스 선언에 추가해야 합니다.
먼저 서비스가 HostApduService
인터페이스를 구현하는 HCE 서비스이라는 것을 플랫폼에 알리려면 서비스 선언에 SERVICE_INTERFACE
작업 관련 인텐트 필터가 포함되어 있어야 합니다.
또한 이 서비스에서 요청한 AID 그룹을 플랫폼에 알리려면 서비스 선언에 SERVICE_META_DATA
<meta-data>
태그를 포함해야 하며 HCE 서비스에 관한 추가 정보가 있는 XML 리소스를 가리켜야 합니다.
마지막으로 android:exported
속성을 true로 설정해야 하며 서비스 선언에 "android.permission.BIND_NFC_SERVICE"
권한이 필요합니다.
전자는 서비스가 외부 애플리케이션에 의해 결합될 수 있도록 합니다.
후자는 "android.permission.BIND_NFC_SERVICE"
권한을 보유한 외부 애플리케이션만 서비스에 결합할 수 있도록 합니다. "android.permission.BIND_NFC_SERVICE"
는 시스템 권한이므로 이 설정을 통해 실질적으로 Android OS만 서비스에 결합할 수 있습니다.
다음은 HostApduService
manifest 선언의 예입니다.
<service android:name=".MyHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"> <intent-filter> <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/> </intent-filter> <meta-data android:name="android.nfc.cardemulation.host_apdu_service" android:resource="@xml/apduservice"/> </service>
이 메타데이터 태그는 apduservice.xml
파일을 가리킵니다. 다음은 두 개의 독점 AID가 포함된 단일 AID 그룹 선언이 있는 파일의 예입니다.
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/servicedesc" android:requireDeviceUnlock="false"> <aid-group android:description="@string/aiddescription" android:category="other"> <aid-filter android:name="F0010203040506"/> <aid-filter android:name="F0394148148100"/> </aid-group> </host-apdu-service>
<host-apdu-service>
태그는 UI에 표시될 수 있는 사용자 친화적인 서비스 설명이 있는 <android:description>
속성을 포함해야 합니다. requireDeviceUnlock
속성을 사용하면 APDU를 처리하기 위해 이 서비스를 호출하기 전에 먼저 기기를 잠금 해제하도록 지정할 수 있습니다.
<host-apdu-service>
는 <aid-group>
태그를 하나 이상 포함해야 합니다. 각 <aid-group>
태그는 다음 작업을 하는 데 필요합니다.
- UI에 표시하기에 적합한 사용자 친화적인 AID 그룹 설명이 있는
android:description
속성을 포함합니다. - AID 그룹이 속한 카테고리(예:
CATEGORY_PAYMENT
또는CATEGORY_OTHER
에 의해 정의된 문자열 상수)를 나타내도록android:category
속성을 설정합니다. - 각
<aid-group>
에는<aid-filter>
태그가 하나 이상 포함되어야 하며 각 태그에는 단일 AID가 포함됩니다. AID는 16진수 형식으로 지정해야 하며 짝수의 문자를 포함해야 합니다.
마지막으로 애플리케이션은 HCE 서비스로 등록할 수 있도록 NFC
권한도 보유해야 합니다.
AID 충돌 해결
단일 기기에 여러 HostApduService
구성요소를 설치할 수 있으며 둘 이상의 서비스에서 동일한 AID를 등록할 수 있습니다. Android 플랫폼은 AID가 속한 카테고리에 따라 AID 충돌을 해결합니다. 카테고리마다 충돌 해결 정책이 다를 수 있습니다.
예를 들어 결제와 같은 일부 카테고리에서 사용자가 Android 설정 UI의 기본 서비스를 선택할 수 있습니다. 기타 카테고리에서는 정책에 따라 충돌 발생 시 호출해야 하는 서비스를 묻는 메시지가 사용자에게 항상 표시될 수 있습니다. 특정 카테고리의 충돌 해결 정책을 쿼리하려면 getSelectionModeForCategory()
를 참조하세요.
서비스가 기본 서비스인지 확인
애플리케이션은 isDefaultServiceForCategory(ComponentName, String)
API를 사용하여 HCE 서비스가 특정 카테고리의 기본 서비스인지 여부를 확인할 수 있습니다.
서비스가 기본 서비스가 아니라면 기본 서비스로 설정하도록 요청할 수 있습니다.
ACTION_CHANGE_DEFAULT
를 참조하세요.
결제 애플리케이션
Android는 '결제' 카테고리가 있는 AID 그룹을 선언한 HCE 서비스를 결제 애플리케이션으로 간주합니다. Android 4.4 버전에는 이러한 결제 애플리케이션을 모두 열거하는 '탭앤페이'라는 최상위 설정 메뉴 항목이 포함되어 있습니다. 이 설정 메뉴에서 사용자는 결제 단말기를 탭할 때 호출할 기본 결제 애플리케이션을 선택할 수 있습니다.
결제 애플리케이션의 필수 애셋
시각적으로 더 매력적인 사용자 환경을 제공하기 위해 HCE 결제 애플리케이션은 서비스 배너라는 서비스를 위한 추가 애셋을 제공해야 합니다.
이 애셋은 크기가 260x96dp여야 하며 드로어블 리소스를 가리키는 <host-apdu-service>
태그에 android:apduServiceBanner
속성을 추가하여 메타데이터 XML 파일에서 지정할 수 있습니다. 아래 예를 참조하세요.
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/servicedesc" android:requireDeviceUnlock="false" android:apduServiceBanner="@drawable/my_banner"> <aid-group android:description="@string/aiddescription" android:category="payment"> <aid-filter android:name="F0010203040506"/> <aid-filter android:name="F0394148148100"/> </aid-group> </host-apdu-service>
화면 꺼짐 및 잠금 화면 동작
현재 Android 구현에서는 기기의 화면이 꺼질 때 NFC 컨트롤러 및 애플리케이션 프로세서가 완전히 꺼집니다. 따라서 HCE 서비스는 화면이 꺼져 있을 때 작동하지 않습니다.
그러나 HCE 서비스는 잠금 화면에서 작동할 수 있으며 이 동작은 HCE 서비스의 <host-apdu-service>
태그에서 android:requireDeviceUnlock
속성으로 제어합니다. 기본적으로 기기 잠금 해제는 필요하지 않으며 기기가 잠겨 있어도 서비스가 호출됩니다.
HCE 서비스의 android:requireDeviceUnlock
속성을 'true'로 설정하면 사용자가 서비스로 확인되는 AID를 선택하는 NFC 리더를 탭할 때 Android에서 사용자에게 기기 잠금을 해제하라는 메시지를 표시합니다. 잠금 해제 후 Android는 트랜잭션을 완료하기 위해 다시 탭하라는 대화상자를 사용자에게 표시합니다. 사용자가 잠금을 해제하기 위해 기기를 NFC 리더로부터 떨어진 거리에서 움직였을 수 있기 때문에 이 메시지가 필요합니다.
보안 요소 카드와의 공존
이 섹션은 카드 에뮬레이션에 보안 요소를 사용하는 애플리케이션을 배포한 개발자에게 유용합니다. Android의 HCE 구현은 보안 요소 사용을 포함하여 카드 에뮬레이션을 구현하는 다른 방법과 동시에 작동하도록 설계되었습니다.
참고: Android는 보안 요소 자체와 직접 통신하기 위한 API를 제공하지 않습니다.
이 공존은 'AID 라우팅'이라는 원칙을 기반으로 합니다. NFC 컨트롤러는 라우팅 규칙의 (한정된) 목록으로 구성된 라우팅 테이블을 유지합니다. 각 라우팅 규칙에는 AID 및 대상이 포함됩니다. 대상은 호스트 CPU(Android 앱이 실행되고 있는) 또는 연결된 보안 요소일 수 있습니다.
NFC 리더가 'SELECT AID'가 있는 APDU를 전송하면 NFC 컨트롤러가 이를 파싱하여 AID가 라우팅 테이블의 AID와 일치하는지 확인합니다. 일치하면 다른 'SELECT AID' APDU가 수신되거나 NFC 링크가 끊길 때까지 APDU 및 그 뒤에 오는 모든 APDU를 AID와 연결된 대상으로 전송합니다.
참고: ISO/IEC 7816-4는 '부분 일치' 개념도 정의하지만 이 개념은 현재 Android HCE 기기에서 지원되지 않습니다.
이 아키텍처는 그림 4에 나와 있습니다.

그림 4. 보안 요소와 호스트 카드 에뮬레이션 모두와 작동하는 Android
또한 NFC 컨트롤러에는 일반적으로 APDU의 기본 경로도 포함됩니다. 라우팅 테이블에 AID가 없을 때 기본 경로가 사용됩니다. 이 설정은 기기마다 다를 수 있지만 Android 기기는 앱에서 등록 중인 AID가 호스트로 적절하게 라우팅되도록 해야 합니다.
HCE 서비스를 구현하거나 보안 요소를 사용하는 Android 애플리케이션은 라우팅 테이블 구성에 관해 신경 쓸 필요가 없습니다. 라우팅 테이블은 Android에서 자동으로 처리됩니다. Android는 어떤 AID를 HCE 서비스에서 처리할 수 있는지와 보안 요소에서 처리할 수 있는지만 알면 됩니다. 설치되어 있는 서비스 및 사용자가 기본으로 사용하도록 구성한 서비스에 따라 라우팅 테이블이 자동으로 구성됩니다.
HCE 서비스의 AID를 선언하는 방법은 이미 설명했습니다. 다음 섹션에서는 카드 에뮬레이션에 보안 요소를 사용하는 애플리케이션의 AID를 선언하는 방법을 설명합니다.
보안 요소 AID 등록
카드 에뮬레이션에 보안 요소를 사용하는 애플리케이션은 manifest에 '오프 호스트 서비스'를 선언할 수 있습니다. 이러한 서비스 선언은 HCE 서비스 선언과 거의 동일합니다. 예외는 다음과 같습니다.
- 인텐트 필터에 사용되는 작업을
SERVICE_INTERFACE
로 설정해야 합니다. - 메타데이터 이름 속성을
SERVICE_META_DATA
로 설정해야 합니다. 메타데이터 XML 파일은
<offhost-apdu-service>
루트 태그를 사용해야 합니다.<service android:name=".MyOffHostApduService" android:exported="true" android:permission="android.permission.BIND_NFC_SERVICE"> <intent-filter> <action android:name="android.nfc.cardemulation.action.OFF_HOST_APDU_SERVICE"/> </intent-filter> <meta-data android:name="android.nfc.cardemulation.off_host_apdu_service" android:resource="@xml/apduservice"/> </service>
다음은 두 개의 AID를 등록하는 apduservice.xml
파일의 예입니다.
<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>
호스트 CPU가 트랜잭션에 관여하지 않으므로 기기가 잠겨 있을 때 보안 요소가 트랜잭션을 실행하는 것을 막을 수 없으므로 android:requireDeviceUnlock
속성은 오프 호스트 서비스에 적용되지 않습니다.
기본 결제 애플리케이션으로 선택 가능하도록 결제 애플리케이션인 오프 호스트 서비스에 android:apduServiceBanner
속성도 사용해야 합니다.
오프 호스트 서비스 호출
Android 자체는 '오프 호스트'로 선언된 서비스를 시작하거나 이 서비스에 결합하지 않습니다. 실제 트랜잭션이 Android 서비스 자체가 아니라 보안 요소에 의해 실행되기 때문입니다. 서비스 선언은 단지 애플리케이션이 보안 요소에 있는 AID를 등록할 수 있게 합니다.
HCE 및 보안
HCE 아키텍처 자체는 하나의 핵심 보안 요소를 제공합니다. 서비스는 BIND_NFC_SERVICE
시스템 권한으로 보호되므로 OS만 서비스에 결합하고 서비스와 통신할 수 있습니다. 따라서 수신된 APDU가 실제로 OS에서 NFC 컨트롤러로부터 수신한 APDU이며 다시 전송된 APDU가 OS로만 이동하므로 결과적으로 APDU를 NFC 컨트롤러에 직접 전달할 수 있습니다.
나머지 핵심 요소는 앱에서 NFC 리더로 전송하는 데이터를 얻는 부분입니다. 이 부분은 HCE 설계에서 의도적으로 분리되어 있습니다. HCE 설계에서는 데이터의 출처를 신경 쓰지 않으며 NFC 컨트롤러와 NFC 리더로까지 안전하게 전송됩니다.
HCE 서비스에서 전송하려는 데이터를 안전하게 저장하고 검색하기 위해서는 예를 들면 앱의 데이터를 다른 앱과 분리하는 Android 애플리케이션 샌드박스를 사용할 수 있습니다. Android 보안에 관한 자세한 내용은 보안 도움말을 참조하세요.
프로토콜 매개변수 및 세부정보
이 섹션은 NFC 프로토콜의 충돌 방지 및 활성화 단계 중에 HCE 기기에서 사용하는 프로토콜 매개변수를 이해하려는 개발자에게 유용합니다. 이러한 이해를 바탕으로 Android HCE 기기와 호환되는 리더 인프라를 구축할 수 있습니다.
Nfc-A(ISO/IEC 14443 Type A) 프로토콜 충돌 방지 및 활성화
Nfc-A 프로토콜 활성화 과정의 일환으로 여러 프레임이 교환됩니다.
교환의 첫 부분에서 HCE 기기는 UID를 제시합니다. HCE 기기에는 임의의 UID가 있다고 가정해야 합니다. 즉, 사용자가 탭할 때마다 리더에 제시되는 UID는 무작위로 생성된 UID입니다. 이 때문에 NFC 리더는 HCE 기기의 UID를 인증 또는 식별의 형태로 사용해서는 안 됩니다.
NFC 리더는 나중에 SEL_REQ 명령을 전송하여 HCE 기기를 선택할 수 있습니다. HCE 기기의 SEL_RES 응답에는 최소한 6번째 비트(0x20)가 설정되며 이 설정은 ISO-DEP를 지원함을 나타냅니다. SEL_RES의 다른 비트들도 설정될 수 있습니다. 예를 들어 NFC-DEP(p2p) 프로토콜 관련 지원을 나타내는 비트도 설정될 수 있습니다. 다른 비트가 설정될 수 있기 때문에 HCE 기기와 상호작용하려는 리더는 6번째 비트만 명확하게 확인해야 하며
ISO-DEP 활성화
Nfc-A 프로토콜이 활성화되면 NFC 리더에서 ISO-DEP 프로토콜 활성화를 시작합니다. NFC 리더는 'RATS(Request for Answer To Select)' 명령을 전송합니다. RATS 응답인 ATS는 전적으로 NFC 컨트롤러에 의해 생성되며 HCE 서비스에서 구성할 수 없습니다. 그러나 HCE 구현이 ATS 응답에 관한 NFC Forum 요구사항을 충족해야 하므로 NFC 리더는 HCE 기기에 관한 NFC Forum 요구사항에 따라 설정되는 이러한 매개변수를 신뢰할 수 있습니다.
아래 섹션에서는 HCE 기기의 NFC 컨트롤러에서 제공하는 ATS 응답의 개별 바이트에 관해 자세히 설명합니다.
- TL: ATS 응답의 길이입니다. 길이가 20바이트보다 크면 안 됩니다.
- T0: 모든 HCE 기기에서 비트 5, 6 및 7이 설정되어야 하며 이 설정은 TA(1), TB(1) 및 TC(1)이 ATS 응답에 포함되어 있음을 나타냅니다. 비트 1~4는 FSCI를 나타내며 최대 프레임 크기를 코딩합니다. HCE 기기의 FSCI 값은 0h에서 8h 사이여야 합니다.
- T(A)1: 리더와 에뮬레이터 간 비트 전송률 및 리더와 에뮬레이터의 비대칭 가능 여부를 정의합니다. HCE 기기의 비트 전송률 요구사항이나 보증은 없습니다.
- T(B)1: 비트 1~4는 SFGI(Start-up Frame Guard time Integer)를 나타냅니다. HCE 기기의 SFGI는 <= 8h여야 합니다. 비트 5~8은 FWI(Frame Waiting time Integer)를 나타내며 FWT(Frame Waiting Time)를 코딩합니다. HCE 기기의 FWI는 <= 8h여야 합니다.
- T(C)1: 비트 5는 '고급 프로토콜 기능' 지원을 나타냅니다. HCE 기기는 '고급 프로토콜 기능'을 지원할 수도 있고 지원하지 않을 수도 있습니다. 비트 2는 DID 지원을 나타냅니다. HCE 기기는 DID를 지원할 수도 있고 지원하지 않을 수도 있습니다. 비트 1은 NAD 지원을 나타냅니다. HCE 기기는 NAD를 지원하지 않아야 하며 비트 1을 0으로 설정해서는 안 됩니다.
- 기록 바이트: HCE 기기는 최대 15개의 기록 바이트를 반환할 수 있습니다. HCE 서비스와 상호작용하려는 NFC 리더는 기록 바이트의 내용이나 존재에 관해 가정해서는 안 됩니다.
많은 HCE 기기가 EMVCo에 통합된 결제 네트워크에서 '미접촉 통신 프로토콜' 사양에 명시한 프로토콜 요구사항을 준수할 가능성이 높습니다. 특히 다음 항목이 중요합니다.
- T0의 FSCI는 2h에서 8h 사이여야 합니다.
- T(A)1은 0x80으로 설정되어야 하며 이 설정은 106kbit/s의 비트 전송률만 지원되며 리더와 에뮬레이터 간 비대칭 비트 전송률은 지원되지 않음을 나타냅니다.
- T(B)1의 FWI는 <= 7h여야 합니다.
APDU 데이터 교환
앞서 언급했듯이 HCE 구현은 단일 논리 채널만 지원합니다. 다른 논리 채널의 애플리케이션을 선택하려고 하면 HCE 기기에서 작동하지 않습니다.