호스트 기반 카드 에뮬레이션 개요

NFC 기능을 제공하는 많은 Android 지원 기기는 이미 NFC 카드 에뮬레이션을 지원합니다. 대부분의 경우 카드는 보안 요소라고 하는 기기의 별도 칩에 의해 에뮬레이션됩니다. 무선 이동통신사에서 제공하는 많은 SIM 카드에도 보안 요소가 포함되어 있습니다.

Android 4.4 이상에서는 호스트 기반 카드 에뮬레이션이라는 보안 요소를 포함하지 않는 추가 카드 에뮬레이션 방법을 제공합니다. 이렇게 하면 모든 Android 애플리케이션에서 카드를 에뮬레이션하고 NFC 리더와 직접 통신할 수 있습니다. 이 주제에서는 Android에서 호스트 기반 카드 에뮬레이션 (HCE)이 작동하는 방식과 이 기법을 사용하여 NFC 카드를 에뮬레이션하는 앱을 개발하는 방법을 설명합니다.

보안 요소가 있는 카드 에뮬레이션

보안 요소를 사용하여 NFC 카드 에뮬레이션을 제공하는 경우 에뮬레이션할 카드는 Android 애플리케이션을 통해 기기의 보안 요소에 프로비저닝됩니다. 그런 다음 사용자가 NFC 단말기에 기기를 대면 기기의 NFC 컨트롤러가 리더의 모든 데이터를 보안 요소로 직접 라우팅합니다. 그림 1은 이 개념을 보여줍니다.

보안 요소에서 정보를 가져오기 위해 NFC 컨트롤러를 통과하는 NFC 리더가 포함된 다이어그램
그림 1. 보안 요소가 있는 NFC 카드 에뮬레이션

보안 요소 자체가 NFC 단말기와의 통신을 실행하며 트랜잭션에 Android 애플리케이션이 포함되지 않습니다. 트랜잭션이 완료되면 Android 애플리케이션이 보안 요소에 직접 트랜잭션 상태를 쿼리하여 사용자에게 알릴 수 있습니다.

호스트 기반 카드 에뮬레이션

NFC 카드가 호스트 기반 카드 에뮬레이션을 사용하여 에뮬레이션되면 데이터는 보안 요소로 라우팅되는 대신 호스트 CPU로 직접 라우팅됩니다. 그림 2는 호스트 기반 카드 에뮬레이션의 작동 방식을 보여줍니다.

NFC 리더가 NFC 컨트롤러를 통해 CPU에서 정보를 검색하는 다이어그램
그림 2. 보안 요소가 없는 NFC 카드 에뮬레이션

지원되는 NFC 카드 및 프로토콜

HCE 프로토콜 스택을 보여주는 다이어그램
그림 3. Android의 HCE 프로토콜 스택

NFC 표준은 다양한 프로토콜을 지원하며 에뮬레이션할 수 있는 다양한 유형의 카드가 있습니다.

Android 4.4 이상은 오늘날 시장에서 일반적으로 사용되는 여러 프로토콜을 지원합니다. 비접촉식 결제 카드와 같은 기존의 많은 비접촉식 카드는 이미 이러한 프로토콜을 기반으로 합니다. 이러한 프로토콜은 리더 자체로 작동하는 Android NFC 기기를 포함하여 오늘날 시장에 있는 많은 NFC 리더에서도 지원됩니다 (IsoDep 클래스 참고). 이를 통해 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 유형 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를 등록하고 모든 AID의 기본 핸들러로 설정되어야 할 수 있습니다. 그룹의 일부 AID가 다른 서비스로 이동하는 기능은 지원되지 않습니다.

함께 유지되는 AID 목록을 AID 그룹이라고 합니다. AID 그룹의 모든 AID와 관련하여 Android는 다음 중 하나를 보장합니다.

  • 그룹의 모든 AID가 이 HCE 서비스로 라우팅됩니다.
  • 그룹의 AID는 이 HCE 서비스로 라우팅되지 않습니다 (예: 사용자가 그룹에서 하나 이상의 AID를 요청한 다른 서비스를 선호했기 때문).

즉, 그룹의 일부 AID는 한 HCE 서비스로 라우팅되고 일부는 다른 HCE 서비스로 라우팅될 수 있는 중간 상태는 없습니다.

AID 그룹 및 카테고리

각 AID 그룹을 카테고리와 연결할 수 있습니다. 이렇게 하면 Android에서 HCE 서비스를 카테고리별로 함께 그룹화할 수 있으며, 그러면 사용자는 AID 수준이 아닌 카테고리 수준에서 기본값을 설정할 수 있습니다. 애플리케이션의 사용자 대상 부분에는 AID를 언급하지 마세요. AID는 일반 사용자에게는 아무 의미가 없습니다.

Android 4.4 이상은 다음 두 가지 카테고리를 지원합니다.

HCE 서비스 구현

호스트 기반 카드 에뮬레이션을 사용하여 NFC 카드를 에뮬레이션하려면 NFC 트랜잭션을 처리하는 Service 구성요소를 만들어야 합니다.

HCE 지원 확인

애플리케이션은 FEATURE_NFC_HOST_CARD_EMULATION 기능을 확인하여 기기가 HCE를 지원하는지 확인할 수 있습니다. 애플리케이션의 매니페스트에서 <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) {
       ...
    }
}

Java

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

HostApduService는 재정의하고 구현해야 하는 두 가지 추상 메서드를 선언합니다. 그중 하나인 processCommandApdu()는 NFC 리더가 APDU (애플리케이션 프로토콜 데이터 단위)를 서비스로 전송할 때마다 호출됩니다. APDU는 ISO/IEC 7816-4 사양에 정의되어 있습니다. APDU는 NFC 리더와 HCE 서비스 간에 교환되는 애플리케이션 수준의 패킷입니다. 이 애플리케이션 수준 프로토콜은 반이중입니다. NFC 리더는 APDU 명령어를 전송하고 개발자가 응답 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 등록

평소대로 매니페스트에서 서비스를 선언해야 하지만 서비스 선언에도 몇 가지 추가 요소를 추가해야 합니다.

  1. 플랫폼에 HostApduService 인터페이스를 구현하는 HCE 서비스임을 알리려면 SERVICE_INTERFACE 작업의 인텐트 필터를 서비스 선언에 추가합니다.

  2. 이 서비스에서 요청하는 AID 그룹을 플랫폼에 알리려면 서비스 선언에 HCE 서비스에 관한 추가 정보가 있는 XML 리소스를 가리키는 SERVICE_META_DATA <meta-data> 태그를 포함합니다.

  3. android:exported 속성을 true로 설정하고 서비스 선언에 android.permission.BIND_NFC_SERVICE 권한이 필요합니다. 전자는 서비스가 외부 애플리케이션에 의해 결합될 수 있도록 합니다. 후자는 android.permission.BIND_NFC_SERVICE 권한을 보유한 외부 애플리케이션만 서비스에 바인딩할 수 있도록 강제합니다. android.permission.BIND_NFC_SERVICE는 시스템 권한이기 때문에 Android OS만 서비스에 바인딩될 수 있도록 실질적으로 적용됩니다.

다음은 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>

이 메타데이터 태그는 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> 속성이 있어야 합니다. APDU 처리를 위해 이 서비스를 호출하기 전에 requireDeviceUnlock 속성을 사용하여 기기가 잠금 해제되도록 지정할 수 있습니다.

<host-apdu-service><aid-group> 태그를 하나 이상 포함해야 합니다. 각 <aid-group> 태그는 다음 작업을 실행해야 합니다.

  • AID 그룹의 사용자 친화적인 설명이 포함된 android:description 속성을 포함합니다. 이 설명은 UI에 표시하기에 적합합니다.
  • CATEGORY_PAYMENT 또는 CATEGORY_OTHER로 정의된 문자열 상수와 같이 AID 그룹이 속한 카테고리를 나타내도록 android:category 속성을 설정해야 합니다.
  • <aid-filter> 태그를 하나 이상 포함합니다. 각 태그는 단일 AID를 포함합니다. 16진수 형식으로 AID를 지정하고 짝수의 문자가 포함되어 있는지 확인합니다.

애플리케이션은 HCE 서비스로 등록하려면 NFC 권한도 보유해야 합니다.

AID 충돌 해결

단일 기기에 여러 HostApduService 구성요소를 설치할 수 있으며 둘 이상의 서비스가 동일한 AID를 등록할 수 있습니다. Android는 AID가 속한 카테고리에 따라 AID 충돌을 다르게 해결합니다. 각 카테고리에는 충돌 해결 정책이 다를 수 있습니다.

결제와 같은 일부 카테고리의 경우 사용자가 Android 설정 UI에서 기본 서비스를 선택할 수 있습니다. 다른 카테고리에서는 정책이 충돌 시 호출할 서비스를 사용자에게 항상 묻는 것일 수 있습니다. 특정 카테고리의 충돌 해결 정책을 쿼리하는 방법에 관한 자세한 내용은 getSelectionModeForCategory()를 참고하세요.

서비스가 기본 서비스인지 확인

애플리케이션은 isDefaultServiceForCategory() API를 사용하여 HCE 서비스가 특정 카테고리의 기본 서비스인지 확인할 수 있습니다.

서비스가 기본값이 아닌 경우 ACTION_CHANGE_DEFAULT를 사용하여 해당 서비스를 기본값으로 설정하도록 요청할 수 있습니다.

결제 애플리케이션

Android는 결제 카테고리가 있는 AID 그룹을 선언한 HCE 서비스를 결제 애플리케이션으로 간주합니다. Android 4.4 이상에는 탭앤페이라는 최상위 설정 메뉴 항목이 포함되어 있으며 여기에는 이러한 결제 애플리케이션이 모두 열거되어 있습니다. 이 설정 메뉴에서 사용자는 결제 단말기를 탭할 때 호출할 기본 결제 애플리케이션을 선택할 수 있습니다.

결제 애플리케이션의 필수 애셋

시각적으로 더 매력적인 사용자 환경을 제공하기 위해 HCE 결제 애플리케이션은 서비스 배너를 제공해야 합니다.

Android 13 이상

설정 UI에 기본 결제 선택 목록에 더 잘 맞도록 배너 요구사항을 정사각형 아이콘으로 조정합니다. 애플리케이션 런처 아이콘 디자인과 동일한 것이 좋습니다. 이 조정을 통해 더욱 일관성 있고 깔끔하게 보이도록 할 수 있습니다.

Android 12 및 이전 버전

서비스 배너 크기를 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>

화면 꺼짐 및 잠금 화면 동작

HCE 서비스의 동작은 기기에서 실행되는 Android 버전에 따라 다릅니다.

Android 12 이상

Android 12 (API 수준 31) 이상을 타겟팅하는 앱에서는 requireDeviceScreenOnfalse로 설정하여 기기 화면이 켜지지 않은 상태에서 NFC 결제를 사용 설정할 수 있습니다.

Android 10 이상

Android 10 (API 수준 29) 이상을 실행하는 기기는 보안 NFC를 지원합니다. 보안 NFC가 사용 설정되어 있으면 기기 화면이 꺼져 있으면 모든 카드 에뮬레이터 (호스트 애플리케이션 및 오프 호스트 애플리케이션)를 사용할 수 없습니다. 보안 NFC가 꺼져 있는 동안에는 기기 화면이 꺼져 있을 때 오프 호스트 애플리케이션을 사용할 수 있습니다. isSecureNfcSupported()를 사용하여 보안 NFC 지원을 확인할 수 있습니다.

Android 10 이상을 실행하는 기기에서는 android:requireDeviceUnlocktrue로 설정하는 것과 동일한 기능이 Android 9 이하를 실행하는 기기와 동일하게 적용되지만 보안 NFC가 사용 중지된 경우에만 적용됩니다. 즉, 보안 NFC가 사용 설정되어 있으면 HCE 서비스는 android:requireDeviceUnlock 설정과 관계없이 잠금 화면에서 작동할 수 없습니다.

Android 9 및 이전 버전

Android 9 (API 수준 28) 이하를 실행하는 기기에서는 기기 화면이 꺼지면 NFC 컨트롤러와 애플리케이션 프로세서가 완전히 꺼집니다. 따라서 HCE 서비스는 화면이 꺼져 있을 때 작동하지 않습니다.

또한 Android 9 이하에서는 HCE 서비스가 잠금 화면에서 작동할 수 있습니다. 그러나 이는 HCE 서비스의 <host-apdu-service> 태그에 있는 android:requireDeviceUnlock 속성으로 제어됩니다. 기본적으로 기기 잠금 해제는 필요하지 않으며 기기가 잠겨 있어도 서비스가 호출됩니다.

HCE 서비스의 android:requireDeviceUnlock 속성을 true로 설정하면 Android는 다음과 같은 경우에 사용자에게 기기를 잠금 해제하라는 메시지를 표시합니다.

  • 사용자가 NFC 리더를 탭합니다.
  • NFC 리더가 서비스로 확인되는 AID를 선택합니다.

잠금 해제 후 Android는 사용자에게 트랜잭션을 완료하려면 다시 탭하라는 대화상자를 표시합니다. 이는 사용자가 잠금을 해제하기 위해 기기를 NFC 리더에서 떨어뜨렸을 수 있기 때문에 필요합니다.

보안 요소 카드와의 공존

이 섹션은 카드 에뮬레이션에 보안 요소를 사용하는 애플리케이션을 배포한 개발자에게 유용합니다. Android의 HCE 구현은 보안 요소 사용을 포함하여 카드 에뮬레이션을 구현하는 다른 방법과 동시에 작동하도록 설계되었습니다.

이러한 공존은 AID 라우팅이라는 원칙을 기반으로 합니다. NFC 컨트롤러는 라우팅 규칙 (유한한) 목록으로 구성된 라우팅 테이블을 유지합니다. 각 라우팅 규칙에는 AID 및 대상이 포함됩니다. 대상은 Android 앱이 실행되는 호스트 CPU이거나 연결된 보안 요소일 수 있습니다.

NFC 리더가 SELECT AID가 있는 APDU를 전송하면 NFC 컨트롤러가 이를 파싱하여 AID가 라우팅 테이블의 AID와 일치하는지 확인합니다. 일치하는 경우 APDU와 그 뒤에 오는 모든 APDU는 다른 SELECT AID APDU가 수신되거나 NFC 링크가 깨질 때까지 AID와 연결된 대상으로 전송됩니다.

그림 4는 이 아키텍처를 보여줍니다.

보안 요소 및 CPU와 통신하는 NFC 판독기 다이어그램
그림 4. 보안 요소와 호스트 카드 에뮬레이션 모두와 함께 작동하는 Android

또한 NFC 컨트롤러에는 일반적으로 APDU의 기본 경로도 포함됩니다. 라우팅 테이블에서 AID를 찾을 수 없으면 기본 경로가 사용됩니다. 이 설정은 기기마다 다를 수 있지만 Android 기기는 앱에서 등록 중인 AID가 호스트에 제대로 라우팅되도록 해야 합니다.

HCE 서비스를 구현하거나 보안 요소를 사용하는 Android 애플리케이션은 라우팅 테이블 구성을 걱정할 필요가 없습니다. 라우팅 테이블은 Android에서 자동으로 처리됩니다. Android는 HCE 서비스에서 처리할 수 있는 AID와 보안 요소에서 처리할 수 있는 AID를 파악하기만 하면 됩니다. 라우팅 테이블은 설치된 서비스와 사용자가 선호하는 서비스로 구성한 서비스에 따라 자동으로 구성됩니다.

다음 섹션에서는 카드 에뮬레이션에 보안 요소를 사용하는 애플리케이션의 AID를 선언하는 방법을 설명합니다.

보안 요소 AID 등록

카드 에뮬레이션에 보안 요소를 사용하는 애플리케이션은 매니페스트에서 오프 호스트 서비스를 선언할 수 있습니다. 이러한 서비스 선언은 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가 실제로 NFC 컨트롤러에서 OS에 의해 수신된 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번째 비트만 명시적으로 확인해야 하며 전체 SEL_RES를 0x20 값과 비교하면 안 됩니다.

ISO-DEP 활성화

Nfc-A 프로토콜이 활성화되면 NFC 리더는 ISO-DEP 프로토콜 활성화를 시작합니다. RATS (Request for Answer To Select) 명령어를 전송합니다. NFC 컨트롤러는 RATS 응답인 ATS를 생성합니다. ATS는 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)를 나타내고 프레임 대기 시간 (FWT)을 코딩합니다. HCE 기기의 FWI는 <= 8h여야 합니다.
  • T(C)1: 비트 5는 '고급 프로토콜 기능' 지원을 나타냅니다. HCE 기기는 '고급 프로토콜 기능'을 지원할 수도 있고 지원하지 않을 수도 있습니다. 비트 2는 DID 지원을 나타냅니다. HCE 기기는 DID를 지원할 수도 있고 지원하지 않을 수도 있습니다. 비트 1은 ND 지원을 나타냅니다. HCE 기기는 NAD를 지원하지 않아야 하며 비트 1을 0으로 설정해서는 안 됩니다.
  • 기록 바이트: HCE 기기는 최대 15개의 기록 바이트를 반환할 수 있습니다. HCE 서비스와 상호작용하려는 NFC 리더는 기록 바이트의 콘텐츠나 존재 여부에 관해 가정해서는 안 됩니다.

많은 HCE 기기는 EMVCo에 통합된 결제 네트워크가 '비접촉 통신 프로토콜' 사양에 지정한 프로토콜 요구사항을 준수할 가능성이 높습니다. 특히 다음 항목이 중요합니다.

  • T0의 FSCI는 2h에서 8h 사이여야 합니다.
  • T(A)1은 0x80으로 설정되어야 합니다. 이는 106kbit/초의 비트 전송률만 지원되며 리더와 에뮬레이터 간의 비대칭 비트 전송률은 지원되지 않음을 나타냅니다.
  • T(B)1의 FWI는 <= 7h여야 합니다.

APDU 데이터 교환

앞서 언급했듯이 HCE 구현은 단일 논리 채널만 지원합니다. 다른 논리 채널의 애플리케이션을 선택하려고 하면 HCE 기기에서 작동하지 않습니다.