ภาพรวมโปรแกรมจำลองการ์ดแบบโฮสต์

อุปกรณ์ Android จำนวนมากที่ให้บริการฟังก์ชัน NFC รองรับการจําลองบัตร NFC อยู่แล้ว ในกรณีส่วนใหญ่ ชิปแยกต่างหากในอุปกรณ์จะจำลองบัตร ซึ่งเรียกว่าองค์ประกอบที่ปลอดภัย ซิมการ์ดจำนวนมากที่ผู้ให้บริการเครือข่ายไร้สายมีให้ก็มีองค์ประกอบที่ปลอดภัยด้วย

Android 4.4 ขึ้นไปมีวิธีการจำลองบัตรเพิ่มเติมที่ไม่เกี่ยวข้องกับองค์ประกอบที่ปลอดภัย ซึ่งเรียกว่าการจำลองบัตรแบบโฮสต์ ซึ่งช่วยให้แอปพลิเคชัน Android จำลองบัตรและสื่อสารกับเครื่องอ่าน NFC ได้โดยตรง หัวข้อนี้จะอธิบายวิธีการทำงานของโปรแกรมจำลองการ์ดแบบโฮสต์ (HCE) ใน Android และวิธีพัฒนาแอปที่จำลองการ์ด NFC โดยใช้เทคนิคนี้

การจําลองบัตรด้วยองค์ประกอบความปลอดภัย

เมื่อมีการจำลองบัตร NFC โดยใช้องค์ประกอบความปลอดภัย ระบบจะจัดสรรบัตรที่จะจําลองลงในองค์ประกอบความปลอดภัยบนอุปกรณ์ผ่านแอปพลิเคชัน Android จากนั้นเมื่อผู้ใช้ถืออุปกรณ์เหนือเครื่องอ่าน NFC ตัวควบคุม NFC ในอุปกรณ์จะส่งข้อมูลทั้งหมดจากเครื่องอ่านไปยังองค์ประกอบที่ปลอดภัยโดยตรง รูปที่ 1 แสดงแนวคิดนี้

แผนภาพด้วยตัวอ่าน NFC ที่กำลังผ่านตัวควบคุม NFC เพื่อดึงข้อมูลจากองค์ประกอบความปลอดภัย
รูปที่ 1. การจำลองบัตร NFC พร้อมองค์ประกอบความปลอดภัย

องค์ประกอบที่ปลอดภัยจะสื่อสารกับเครื่องชำระเงิน NFC และไม่มีแอปพลิเคชัน Android ใดๆ เกี่ยวข้องกับธุรกรรม หลังจากธุรกรรมเสร็จสมบูรณ์แล้ว แอปพลิเคชัน Android จะค้นหาสถานะธุรกรรมจากองค์ประกอบที่ปลอดภัยได้โดยตรงและแจ้งให้ผู้ใช้ทราบ

โปรแกรมจำลองการ์ดแบบโฮสต์

เมื่อมีการจำลองการ์ด NFC โดยใช้การจำลองการ์ดแบบโฮสต์ ระบบจะกำหนดเส้นทางข้อมูลไปยัง CPU ของโฮสต์โดยตรงแทนที่จะส่งไปยังองค์ประกอบที่ปลอดภัย รูปที่ 2 แสดงวิธีการทำงานของโปรแกรมจำลองการ์ดแบบโฮสต์

แผนภาพที่มีเครื่องอ่าน NFC ผ่านตัวควบคุม NFC เพื่อดึงข้อมูลจาก CPU
รูปที่ 2 การจําลองบัตร NFC ที่ไม่มีองค์ประกอบความปลอดภัย

บัตรและโปรโตคอล NFC ที่รองรับ

แผนภาพแสดงสแต็กโปรโตคอล HCE
รูปที่ 3 สแต็กโปรโตคอล HCE ของ Android

มาตรฐาน NFC รองรับโปรโตคอลต่างๆ มากมาย และมีการ์ดประเภทต่างๆ ที่คุณจําลองได้

Android 4.4 ขึ้นไปรองรับโปรโตคอลหลายแบบที่ใช้กันทั่วไปในตลาดปัจจุบัน บัตรแบบไม่ต้องสัมผัสที่มีอยู่หลายใบที่อิงตามโปรโตคอลเหล่านี้อยู่แล้ว เช่น บัตรสำหรับชำระเงินแบบไม่ต้องสัมผัส นอกจากนี้ โปรแกรมอ่าน NFC จำนวนมากในตลาดในปัจจุบันยังรองรับโปรโตคอลเหล่านี้ด้วย รวมถึงอุปกรณ์ NFC ของ Android ที่ทำหน้าที่เป็นโปรแกรมอ่านเอง (ดูคลาส IsoDep) ซึ่งช่วยให้คุณสร้างและติดตั้งใช้งานโซลูชัน NFC จากต้นทางถึงปลายทางใน HCE โดยใช้เฉพาะอุปกรณ์ที่ใช้ Android ได้

กล่าวโดยละเอียดคือ Android 4.4 ขึ้นไปรองรับการจําลองบัตรที่อิงตามข้อกําหนด ISO-DEP ของ NFC-Forum (อิงตาม ISO/IEC 14443-4) และประมวลผล Application Protocol Data Unit (APDU) ตามที่ระบุไว้ในข้อกําหนด ISO/IEC 7816-4 Android กำหนดให้จําลอง ISO-DEP บนเทคโนโลยี Nfc-A (ISO/IEC 14443-3 ประเภท A) เท่านั้น รองรับเทคโนโลยี NFC-B (ISO/IEC 14443-4 ประเภท B) เป็นตัวเลือกที่ไม่บังคับ รูปที่ 3 แสดงการวางซ้อนของข้อกําหนดทั้งหมดเหล่านี้

บริการ HCE

สถาปัตยกรรม HCE ใน Android อิงตามคอมโพเนนต์ AndroidService (หรือที่เรียกว่าบริการ HCE) ข้อดีที่สำคัญอย่างหนึ่งของบริการคือสามารถทำงานในเบื้องหลังได้โดยไม่ต้องใช้อินเทอร์เฟซผู้ใช้ ตัวเลือกนี้เหมาะสำหรับแอปพลิเคชัน HCE หลายแอป เช่น บัตรสะสมคะแนนหรือบัตรโดยสาร ซึ่งผู้ใช้ไม่ควรต้องเปิดแอปเพื่อใช้งาน แต่การแตะอุปกรณ์กับเครื่องอ่าน NFC จะเริ่มต้นบริการที่ถูกต้องหากยังไม่ได้ทำงานอยู่ และดำเนินการธุรกรรมในเบื้องหลัง แน่นอนว่าคุณเปิด UI เพิ่มเติม (เช่น การแจ้งเตือนผู้ใช้) จากบริการของคุณได้ตามความเหมาะสม

การเลือกบริการ

เมื่อผู้ใช้แตะอุปกรณ์กับเครื่องอ่าน NFC ระบบ Android ต้องทราบว่าโปรแกรมอ่าน NFC ต้องการสื่อสารด้วยบริการ HCE ใด ข้อกำหนด ISO/IEC 7816-4 กำหนดวิธีเลือกแอปพลิเคชันโดยมุ่งเน้นที่รหัสแอปพลิเคชัน (AID) AID ประกอบด้วยไบต์ได้สูงสุด 16 ไบต์ หากคุณจำลองบัตรสำหรับโครงสร้างพื้นฐานเครื่องอ่าน NFC ที่มีอยู่ AID ที่เครื่องอ่านเหล่านั้นมองหามักจะเป็น AID ที่รู้จักกันดีและจดทะเบียนแบบสาธารณะ (เช่น AID ของเครือข่ายการชำระเงิน เช่น Visa และ MasterCard)

หากต้องการใช้โครงสร้างพื้นฐานเครื่องอ่านใหม่สำหรับแอปพลิเคชันของคุณ คุณจะต้องลงทะเบียน AID ของคุณเอง ขั้นตอนการจดทะเบียน AID ระบุไว้ในข้อกำหนด ISO/IEC 7816-5 เราขอแนะนำให้ลงทะเบียน AID ตามมาตรฐาน 7816-5 หากคุณกำลังติดตั้งใช้งานแอปพลิเคชัน HCE สำหรับ Android เนื่องจากจะช่วยหลีกเลี่ยงการทับซ้อนกับแอปพลิเคชันอื่นๆ

กลุ่ม AID

ในบางกรณี บริการ HCE อาจต้องลงทะเบียน AID หลายรายการและตั้งค่าเป็นตัวแฮนเดิลเริ่มต้นสำหรับ AID ทั้งหมดเพื่อใช้งานแอปพลิเคชันบางอย่าง ระบบไม่รองรับเอดส์บางรายการในกลุ่มที่จะเปลี่ยนไปใช้บริการอื่น

รายการ AID ที่เก็บไว้ด้วยกันเรียกว่ากลุ่ม AID สำหรับเอดส์ทั้งหมดในกลุ่ม AID นั้น Android รับประกันข้อใดข้อหนึ่งต่อไปนี้

  • ระบบจะกำหนดเส้นทาง AID ทั้งหมดในกลุ่มไปยังบริการ HCE นี้
  • ไม่มีการกำหนดเส้นทาง AID ในกลุ่มไปยังบริการ HCE นี้ (เช่น เนื่องจากผู้ใช้ต้องการบริการอื่นที่ขอ AID อย่างน้อย 1 รายการในกลุ่มของคุณด้วย)

กล่าวคือ ไม่มีสถานะกลางๆ ที่ AID บางรายการในกลุ่มสามารถกำหนดเส้นทางไปยังบริการ HCE หนึ่ง และกำหนดเส้นทาง AID บางรายการไปยังบริการอื่น

กลุ่มและหมวดหมู่ AID

คุณสามารถเชื่อมโยงกลุ่ม AID แต่ละกลุ่มกับหมวดหมู่ได้ ซึ่งจะช่วยให้ Android จัดกลุ่มบริการ HCE ไว้ด้วยกันตามหมวดหมู่ และช่วยให้ผู้ใช้กำหนดค่าเริ่มต้นที่ระดับหมวดหมู่แทนระดับ AID ได้ หลีกเลี่ยงการพูดถึง AIDs ในส่วนที่แสดงต่อผู้ใช้ของแอปพลิเคชัน เนื่องจาก AIDs ไม่ได้มีความหมายใดๆ สำหรับผู้ใช้ทั่วไป

Android 4.4 ขึ้นไปรองรับ 2 หมวดหมู่ดังนี้

  • CATEGORY_PAYMENT (ครอบคลุมแอปการชำระเงินมาตรฐานอุตสาหกรรม)
  • CATEGORY_OTHER (สำหรับแอป HCE อื่นๆ ทั้งหมด)

ติดตั้งใช้งานบริการ HCE

หากต้องการจําลองบัตร NFC โดยใช้การจําลองบัตรแบบโฮสต์ คุณต้องสร้างคอมโพเนนต์ Service ที่จัดการธุรกรรม NFC

ตรวจสอบการรองรับ HCE

แอปพลิเคชันสามารถตรวจสอบว่าอุปกรณ์รองรับ HCE หรือไม่โดยตรวจสอบฟีเจอร์ FEATURE_NFC_HOST_CARD_EMULATION ใช้แท็ก <uses-feature> ในไฟล์ Manifest ของแอปพลิเคชันเพื่อประกาศว่าแอปของคุณใช้ฟีเจอร์ HCE และจำเป็นต้องใช้ฟีเจอร์ดังกล่าวเพื่อให้แอปทำงานหรือไม่

การติดตั้งใช้งานบริการ

Android 4.4 ขึ้นไปมีคลาส Service ที่สะดวกซึ่งคุณใช้เป็นพื้นฐานสำหรับการใช้บริการ HCE ได้ ซึ่งก็คือคลาส 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 ประกาศเมธอดนามธรรม 2 รายการที่คุณต้องลบล้างและนำไปใช้ หนึ่งในนั้นคือ processCommandApdu() ซึ่งจะเรียกใช้ทุกครั้งที่เครื่องอ่าน NFC ส่ง Application Protocol Data Unit (APDU) ไปยังบริการของคุณ APDU ได้รับการกําหนดไว้ในข้อกําหนด ISO/IEC 7816-4 APDU คือแพ็กเก็ตระดับแอปพลิเคชันที่แลกเปลี่ยนกันระหว่างเครื่องอ่าน NFC กับบริการ HCE ของคุณ โปรโตคอลระดับแอปพลิเคชันนั้นเป็นแบบครึ่งดูเพล็กซ์ โดยเครื่องอ่าน NFC จะส่ง APDU คำสั่งให้คุณ แล้วรอให้คุณส่ง APDU การตอบกลับ

ดังที่ได้กล่าวไว้ก่อนหน้านี้ Android จะใช้ AID เพื่อระบุบริการ HCE ที่เครื่องอ่านต้องการพูดคุยด้วย โดยปกติแล้ว APDU รายการแรกที่เครื่องอ่าน NFC ส่งไปยังอุปกรณ์ของคุณคือ SELECT AID APDU ซึ่ง APDU นี้มี AID ที่เครื่องอ่านต้องการสื่อสารด้วย Android จะดึงข้อมูล AID นั้นจาก APDU แล้วแปลงเป็นบริการ HCE จากนั้นส่งต่อ APDU นั้นไปยังบริการที่แปลงแล้ว

คุณสามารถส่ง APDU การตอบกลับได้โดยส่งคืนไบต์ของ APDU การตอบกลับจาก processCommandApdu() โปรดทราบว่าเมธอดนี้จะเรียกใช้ในเธรดหลักของแอปพลิเคชัน ซึ่งคุณไม่ควรบล็อก หากคำนวณและแสดง APDU การตอบกลับทันทีไม่ได้ ให้แสดงผลเป็น Null จากนั้นคุณทํางานที่จำเป็นในอีกเธรดหนึ่งและใช้เมธอด sendResponseApdu() ที่กําหนดไว้ในคลาส HostApduService เพื่อส่งการตอบกลับเมื่อทําเสร็จแล้ว

Android จะส่งต่อ APDU ใหม่จากเครื่องอ่านไปยังบริการของคุณต่อไปจนกว่าจะเกิดเหตุการณ์ใดเหตุการณ์หนึ่งต่อไปนี้

  • เครื่องอ่าน NFC จะส่ง SELECT AID APDU อื่น ซึ่งระบบปฏิบัติการจะแก้ไขเป็นบริการอื่น
  • ลิงก์ NFC ระหว่างเครื่องอ่าน NFC กับอุปกรณ์ของคุณเสีย

ในทั้ง 2 กรณีนี้ ระบบจะเรียกใช้การติดตั้งใช้งาน onDeactivated() ของชั้นเรียนด้วยอาร์กิวเมนต์ที่ระบุว่าสิ่งใดเกิดขึ้นจาก 2 กรณี

หากคุณทำงานกับโครงสร้างพื้นฐานผู้อ่านที่มีอยู่เดิม คุณต้องใช้โปรโตคอลระดับแอปพลิเคชันที่มีอยู่ซึ่งผู้อ่านคาดหวังในบริการ HCE ของคุณ

หากกำลังติดตั้งใช้งานโครงสร้างพื้นฐานเครื่องอ่านแบบใหม่ที่คุณควบคุมด้วย คุณก็กำหนดโปรโตคอลและลําดับ APDU ของคุณเองได้ พยายามจำกัดจำนวน APDU และขนาดของข้อมูลที่แลกเปลี่ยน: วิธีนี้จะช่วยให้ผู้ใช้ต้องถืออุปกรณ์เหนือเครื่องอ่าน NFC เพียงระยะเวลาสั้นๆ ขอบเขตบนที่เหมาะสมคือข้อมูลประมาณ 1 KB ซึ่งโดยปกติจะแลกเปลี่ยนได้ภายใน 300 ms

การประกาศไฟล์ Manifest ของบริการและการลงทะเบียน AID

คุณต้องประกาศบริการในไฟล์ Manifest ตามปกติ แต่ต้องเพิ่มข้อมูลบางอย่างในการประกาศบริการด้วย

  1. หากต้องการบอกแพลตฟอร์มว่าเป็นบริการ HCE ที่ใช้HostApduServiceอินเทอร์เฟซ ให้เพิ่มตัวกรอง Intent สําหรับการดำเนินการ SERVICE_INTERFACE ลงในประกาศบริการ

  2. หากต้องการบอกแพลตฟอร์มว่าบริการนี้ขอกลุ่ม AID ใด ให้ใส่แท็ก SERVICE_META_DATA <meta-data> ในการประกาศบริการ ซึ่งชี้ไปยังแหล่งข้อมูล XML ที่มีข้อมูลเพิ่มเติมเกี่ยวกับบริการ HCE

  3. ตั้งค่าแอตทริบิวต์ android:exported เป็น true และกำหนดสิทธิ์ android.permission.BIND_NFC_SERVICE ในการประกาศบริการ ตัวเลือกแรกช่วยให้แอปพลิเคชันภายนอกสามารถเชื่อมโยงกับบริการได้ จากนั้นนโยบายนี้จะบังคับให้มีเพียงแอปพลิเคชันภายนอกที่มีสิทธิ์ android.permission.BIND_NFC_SERVICE เท่านั้นที่จะสามารถเชื่อมโยงกับบริการของคุณได้ เนื่องจาก android.permission.BIND_NFC_SERVICE เป็นสิทธิ์ของระบบ การดำเนินการนี้จะบังคับใช้อย่างมีประสิทธิภาพว่ามีเพียงระบบปฏิบัติการ Android เท่านั้นที่เชื่อมโยงกับบริการของคุณได้

ต่อไปนี้เป็นตัวอย่างการประกาศในไฟล์ Manifest ของ 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 ที่เป็นกรรมสิทธิ์ 2 รายการ

<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> ต้องมีแอตทริบิวต์ <android:description> ที่มีคำอธิบายบริการที่เข้าใจง่ายซึ่งคุณสามารถแสดงใน UI ของแอป คุณสามารถใช้แอตทริบิวต์ requireDeviceUnlock เพื่อระบุว่าอุปกรณ์ปลดล็อกอยู่ก่อนที่จะเรียกใช้บริการนี้เพื่อจัดการ APDU

<host-apdu-service> ต้องมีแท็ก <aid-group> อย่างน้อย 1 แท็ก แท็ก <aid-group> แต่ละรายการต้องทําสิ่งต่อไปนี้

  • มีแอตทริบิวต์ android:description ที่มีคำอธิบายกลุ่ม AID ที่เข้าใจง่ายและเหมาะสำหรับแสดงใน UI
  • ตั้งค่าแอตทริบิวต์ android:category เพื่อระบุหมวดหมู่ของกลุ่ม AID เช่น ค่าคงที่สตริงที่กําหนดโดย CATEGORY_PAYMENT หรือ CATEGORY_OTHER
  • มีแท็ก <aid-filter> อย่างน้อย 1 รายการ โดยแต่ละแท็กมี AID รายการเดียว ระบุ AID ในรูปแบบเลขฐานสิบหก และตรวจสอบว่าอักขระมีจำนวนคู่

นอกจากนี้ แอปพลิเคชันของคุณต้องมีสิทธิ์ NFC เพื่อลงทะเบียนเป็นบริการ HCE ด้วย

การแก้ไขข้อขัดแย้งของ AID

คุณสามารถติดตั้งคอมโพเนนต์ HostApduService หลายรายการในอุปกรณ์เครื่องเดียว และบริการมากกว่า 1 รายการสามารถลงทะเบียน AID เดียวกันได้ Android จะกำหนดบริการที่จะเรียกใช้โดยใช้ขั้นตอนต่อไปนี้

  1. หากแอปกระเป๋าสตางค์เริ่มต้นที่ผู้ใช้เลือกได้ลงทะเบียน AID แล้ว ระบบจะเรียกใช้แอปนั้น
  2. หากแอป Wallet เริ่มต้นไม่ได้ลงทะเบียน AID ระบบจะเรียกใช้บริการที่ลงทะเบียน AID
  3. หากมีมากกว่า 1 บริการได้ลงทะเบียน AID แล้ว Android จะถามผู้ใช้ว่าต้องการเรียกใช้บริการใด

ตรวจสอบว่าแอปของคุณเป็นแอปกระเป๋าเงินเริ่มต้นหรือไม่

แอปสามารถตรวจสอบว่าเป็นแอป Wallet เริ่มต้นหรือไม่ได้โดยส่ง RoleManager.ROLE_WALLET ไปยัง RoleManager.isRoleHeld()

หากแอปของคุณไม่ใช่แอปเริ่มต้น คุณสามารถขอบทบาทกระเป๋าเงินเริ่มต้นได้โดยส่ง RoleManager.ROLE_WALLET ไปยัง RoleManager.createRequestRoleIntent()

แอปพลิเคชัน Wallet

Android จะถือว่าบริการ HCE ที่ประกาศกลุ่ม AID ที่มีหมวดหมู่การชำระเงินเป็นแอปพลิเคชันเวิล์ต Android 15 ขึ้นไปมีบทบาทแอป Wallet เริ่มต้นที่ผู้ใช้สามารถเลือกได้โดยไปที่การตั้งค่า > แอป > แอปเริ่มต้น ซึ่งจะกำหนดแอปพลิเคชัน Wallet เริ่มต้นที่จะเรียกใช้เมื่อมีการแตะเครื่องชำระเงิน

เนื้อหาที่จำเป็นสำหรับแอปพลิเคชัน Wallet

แอปพลิเคชันกระเป๋าเงิน HCE ต้องมีแบนเนอร์บริการเพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดึงดูดสายตามากขึ้น

Android 13 ขึ้นไป

เพื่อให้พอดีกับรายการตัวเลือกการชำระเงินเริ่มต้นใน UI การตั้งค่า ให้ปรับข้อกำหนดแบนเนอร์เป็นไอคอนสี่เหลี่ยมจัตุรัส ตามหลักการแล้ว ไอคอนนี้ควรเหมือนกับการออกแบบ ไอคอน Launcher ของแอปพลิเคชัน การปรับนี้ทำให้ดูสอดคล้องกันมากขึ้นและดูสะอาดตาขึ้น

Android 12 และต่ำกว่า

กำหนดขนาดของแบนเนอร์บริการเป็น 260x96 dp แล้วตั้งค่าขนาดของแบนเนอร์บริการในไฟล์ XML ข้อมูลเมตาโดยเพิ่มแอตทริบิวต์ android:apduServiceBanner ลงในแท็ก <host-apdu-service> ซึ่งชี้ไปยังทรัพยากรที่ถอนออกได้ ตัวอย่างมีดังนี้

<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 15 เปิดตัวฟีเจอร์โหมดสังเกตการณ์ เมื่อเปิดใช้ โหมดสังเกตการณ์จะอนุญาตให้อุปกรณ์สังเกตการณ์ลูปการสำรวจ NFC และส่งการแจ้งเตือนเกี่ยวกับลูปเหล่านั้นไปยังคอมโพเนนต์ HostApduService ที่เหมาะสมเพื่อให้คอมโพเนนต์เตรียมพร้อมที่จะโต้ตอบกับเครื่องชำระเงิน NFC เครื่องหนึ่งๆ HostApduService สามารถทำให้อุปกรณ์เข้าสู่โหมดสังเกตการณ์ได้โดยส่ง true ไปยัง setObserveModeEnabled() ซึ่งจะเป็นการสั่งสแต็ก NFC ไม่ให้ทำธุรกรรม NFC และสังเกตการวนซ้ำแบบแพสซีฟแทน

ตัวกรองลูปแบบสำรวจ

คุณสามารถลงทะเบียนตัวกรองลูปการโหวตสําหรับ HostApduService ได้โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้

เมื่อตัวกรองลูปการสำรวจตรงกับเฟรมการสำรวจที่ไม่เป็นมาตรฐาน สแต็ก NFC จะกำหนดเส้นทางเฟรมการสำรวจเหล่านั้นไปยัง HostApduService ที่เกี่ยวข้องโดยเรียกใช้เมธอด processPollingFrames() ของ HostApduService ซึ่งจะช่วยให้บริการดำเนินการตามขั้นตอนที่จำเป็นเพื่อให้มั่นใจว่าผู้ใช้พร้อมทำธุรกรรมและตั้งใจที่จะทำเช่นนั้น เช่น การตรวจสอบสิทธิ์ผู้ใช้ หากเครื่องอ่าน NFC ใช้เฉพาะเฟรมมาตรฐานในลูปการสำรวจ สแต็ก NFC จะกำหนดเส้นทางเฟรมการสำรวจเหล่านั้นไปยังบริการที่ทำงานอยู่เบื้องหน้าที่ต้องการ หากบริการดังกล่าวทำงานอยู่เบื้องหน้า หรือไปยังผู้ถือบทบาทเริ่มต้นของ Wallet

นอกจากนี้ การแจ้งเตือนเฟรมแบบสำรวจจะมีการวัดความแรงของช่องข้อมูลเฉพาะผู้ให้บริการ ซึ่งคุณสามารถดึงข้อมูลได้โดยเรียกใช้ getVendorSpecificGain() ผู้ให้บริการสามารถระบุการวัดโดยใช้มาตราส่วนของตนเอง ตราบใดที่ข้อมูลดังกล่าวอยู่ภายในไบต์เดียว

ตอบสนองต่อลูปการโหวตและออกจากโหมดสังเกตการณ์

เมื่อบริการพร้อมทำธุรกรรมแล้ว บริการจะออกจากโหมดสังเกตการณ์ได้โดยส่ง false ไปยัง setObserveModeEnabled() จากนั้นสแต็ก NFC จะอนุญาตให้ทำธุรกรรมต่อ

คอมโพเนนต์ HostApduService สามารถระบุได้ว่าควรเปิดใช้โหมดสังเกตเมื่อใดก็ตามที่เป็นบริการชำระเงินที่ต้องการ โดยการตั้งค่า shouldDefaultToObserveMode เป็น true ในไฟล์ Manifest หรือโดยการเรียกใช้ CardEmulation.setShouldDefaultToObserveModeForService()

คอมโพเนนต์ HostApduService และ OffHostApduService ยังระบุได้ด้วยว่าตัวกรองลูปการโหวตที่ตรงกับเฟรมลูปการโหวตที่ได้รับควรปิดใช้โหมดสังเกตการณ์โดยอัตโนมัติและอนุญาตให้ธุรกรรมดำเนินการต่อโดยการตั้งค่า autoTransact เป็น true ในประกาศ PollingLoopFilter ในไฟล์ Manifest

ลักษณะการทํางานของหน้าจอปิดและหน้าจอล็อก

ลักษณะการทำงานของบริการ HCE จะแตกต่างกันไปตามเวอร์ชันของ Android ที่ทำงานในอุปกรณ์

Android 12 ขึ้นไป

ในแอปที่กำหนดเป้าหมายเป็น Android 12 (API ระดับ 31) ขึ้นไป คุณสามารถเปิดใช้การชำระเงิน NFC โดยไม่ต้องเปิดหน้าจอของอุปกรณ์โดยตั้งค่า requireDeviceScreenOn เป็น false

Android 10 ขึ้นไป

อุปกรณ์ที่ใช้ Android 10 (API ระดับ 29) ขึ้นไปรองรับ NFC ที่ปลอดภัย เมื่อ NFC ที่ปลอดภัยเปิดอยู่ โปรแกรมจำลองบัตรทั้งหมด (แอปพลิเคชันโฮสต์และแอปพลิเคชันนอกโฮสต์) จะใช้งานไม่ได้เมื่อหน้าจออุปกรณ์ปิดอยู่ ขณะที่ NFC ที่ปลอดภัยปิดอยู่ แอปพลิเคชันนอกโฮสต์จะใช้งานได้เมื่อหน้าจออุปกรณ์ปิดอยู่ คุณสามารถตรวจสอบการรองรับ NFC ที่ปลอดภัยได้โดยใช้ isSecureNfcSupported()

ในอุปกรณ์ที่ใช้ Android 10 ขึ้นไป ฟังก์ชันการทำงานเดียวกันสำหรับการตั้งค่า android:requireDeviceUnlock เป็น true จะมีผลเหมือนกับอุปกรณ์ที่ใช้ Android 9 และต่ำกว่า แต่เฉพาะเมื่อปิด "รักษาความปลอดภัยของ NFC" ไว้ กล่าวคือ หากเปิด NFC ที่ปลอดภัยไว้ บริการ HCE จะไม่ทำงานจากหน้าจอล็อกไม่ว่าการตั้งค่าของ android:requireDeviceUnlock จะเป็นอย่างไรก็ตาม

Android 9 และต่ำกว่า

ในอุปกรณ์ที่ใช้ Android 9 (API ระดับ 28) และต่ำกว่า ตัวควบคุม NFC และตัวประมวลผลแอปพลิเคชันจะปิดลงอย่างสมบูรณ์เมื่อปิดหน้าจอของอุปกรณ์ ดังนั้นบริการ HCE จึงใช้งานไม่ได้เมื่อหน้าจอปิดอยู่

นอกจากนี้ ใน Android 9 หรือต่ำกว่า บริการ HCE จะทำงานจากหน้าจอล็อกได้ อย่างไรก็ตาม การดำเนินการนี้จะควบคุมโดยแอตทริบิวต์ android:requireDeviceUnlock ในแท็ก <host-apdu-service> ของบริการ HCE โดยค่าเริ่มต้น ระบบจะไม่กำหนดให้ต้องปลดล็อกอุปกรณ์ และระบบจะเรียกใช้บริการของคุณแม้ว่าอุปกรณ์จะล็อกอยู่ก็ตาม

หากคุณตั้งค่าแอตทริบิวต์ android:requireDeviceUnlock เป็น true สำหรับบริการ HCE ของคุณ Android จะแจ้งให้ผู้ใช้ปลดล็อกอุปกรณ์ในกรณีต่อไปนี้

  • ผู้ใช้แตะเครื่องอ่าน NFC
  • เครื่องอ่าน NFC จะเลือก AID ที่แก้ไขไปยังบริการของคุณ

หลังจากปลดล็อกแล้ว Android จะแสดงกล่องโต้ตอบเพื่อแจ้งให้ผู้ใช้แตะอีกครั้งเพื่อดำเนินการธุรกรรมให้เสร็จสมบูรณ์ ซึ่งเป็นสิ่งจำเป็นเนื่องจากผู้ใช้อาจย้ายอุปกรณ์ออกจากเครื่องอ่าน NFC เพื่อปลดล็อกอุปกรณ์

การอยู่ร่วมกันกับการ์ดองค์ประกอบความปลอดภัย

ส่วนนี้จะเป็นประโยชน์สำหรับนักพัฒนาแอปที่ติดตั้งใช้งานแอปพลิเคชันซึ่งอาศัยองค์ประกอบที่ปลอดภัยสำหรับการจําลองบัตร การใช้งาน HCE ของ Android ได้รับการออกแบบให้ทำงานควบคู่ไปกับวิธีการอื่นๆ ในการใช้งานการจําลองบัตร รวมถึงการใช้องค์ประกอบที่ปลอดภัย

การอยู่ร่วมกันนี้อิงตามหลักการที่เรียกว่าการกำหนดเส้นทาง AID ตัวควบคุม NFC จะเก็บตารางการกำหนดเส้นทางที่ประกอบด้วยรายการกฎการกำหนดเส้นทาง (แบบจำกัด) กฎการกำหนดเส้นทางแต่ละข้อจะมี AID และปลายทาง ปลายทางอาจเป็น CPU ของโฮสต์ ที่แอป Android ทำงานอยู่ หรือองค์ประกอบความปลอดภัยที่เชื่อมต่อ

เมื่อเครื่องอ่าน NFC ส่ง APDU ที่มี SELECT AID ตัวควบคุม NFC จะแยกวิเคราะห์และตรวจสอบว่า AID ตรงกับ AID ในตารางการกําหนดเส้นทางหรือไม่ หากตรงกัน ระบบจะส่ง APDU นั้นและ APDU ทั้งหมดที่ตามมาไปยังปลายทางที่เชื่อมโยงกับ AID จนกว่าจะได้รับการตอบกลับ APDU SELECT AID รายการอื่นหรือลิงก์ NFC ขาดการเชื่อมต่อ

รูปที่ 4 แสดงสถาปัตยกรรมนี้

แผนภาพที่โปรแกรมอ่าน NFC สื่อสารกับทั้งองค์ประกอบที่ปลอดภัยและ CPU
รูปที่ 4 Android ที่ทำงานร่วมกับทั้งองค์ประกอบความปลอดภัยและการจําลองบัตรโฮสต์

โดยปกติแล้ว ตัวควบคุม NFC จะมีเส้นทางเริ่มต้นสำหรับ APDU ด้วย เมื่อไม่พบ AID ในตารางการกําหนดเส้นทาง ระบบจะใช้เส้นทางเริ่มต้น แม้ว่าการตั้งค่านี้อาจแตกต่างกันไปในแต่ละอุปกรณ์ แต่อุปกรณ์ Android จะต้องตรวจสอบว่า AID ที่แอปของคุณลงทะเบียนได้รับการส่งไปยังโฮสต์อย่างถูกต้อง

แอปพลิเคชัน Android ที่ใช้บริการ HCE หรือใช้องค์ประกอบที่ปลอดภัยไม่ต้องกังวลเกี่ยวกับการกำหนดค่าตารางเส้นทาง เนื่องจาก Android จะจัดการให้โดยอัตโนมัติ Android เพียงแต่ต้องการทราบว่าบริการ HCE สามารถจัดการโรคเอดส์ใดได้บ้าง และบริการใดซึ่งองค์ประกอบความปลอดภัยสามารถจัดการได้ ระบบจะกําหนดค่าตารางการกําหนดเส้นทางโดยอัตโนมัติตามบริการที่ติดตั้งและบริการที่ผู้ใช้กําหนดค่าไว้

ส่วนต่อไปนี้จะอธิบายวิธีประกาศ AID สําหรับแอปพลิเคชันที่ใช้องค์ประกอบที่ปลอดภัยสำหรับการจําลองบัตร

การลงทะเบียน AID ในองค์ประกอบความปลอดภัย

แอปพลิเคชันที่ใช้องค์ประกอบที่ปลอดภัยสำหรับการจําลองบัตรสามารถประกาศบริการนอกโฮสต์ในไฟล์ Manifest การประกาศบริการนี้แทบจะเหมือนกับการประกาศบริการ HCE ข้อยกเว้นมีดังนี้

  • การดำเนินการที่ใช้ในตัวกรอง Intent ต้องตั้งค่าเป็น 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>

ต่อไปนี้เป็นตัวอย่างไฟล์ apduservice.xml ที่เกี่ยวข้องซึ่งลงทะเบียน AID 2 รายการ

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

แอตทริบิวต์ android:requireDeviceUnlock จะใช้ไม่ได้กับบริการนอกโฮสต์ เนื่องจาก CPU ของโฮสต์ไม่เกี่ยวข้องกับธุรกรรม จึงไม่สามารถป้องกันไม่ให้องค์ประกอบที่ปลอดภัยดำเนินการธุรกรรมเมื่ออุปกรณ์ล็อกอยู่

คุณต้องใช้แอตทริบิวต์ android:apduServiceBanner สำหรับบริการนอกโฮสต์ที่เป็นแอปพลิเคชันการชำระเงินและเพื่อเลือกเป็นแอปพลิเคชันการชำระเงินเริ่มต้น

การเรียกใช้บริการนอกโฮสต์

Android จะไม่เริ่มต้นหรือเชื่อมโยงกับบริการที่ประกาศว่า "ไม่ได้อยู่ในโฮสต์" เนื่องจากธุรกรรมจริงจะดำเนินการโดยองค์ประกอบที่ปลอดภัย ไม่ใช่บริการ Android การประกาศบริการเป็นเพียงการอนุญาตให้แอปพลิเคชันลงทะเบียน AID ที่อยู่ในองค์ประกอบความปลอดภัย

HCE และความปลอดภัย

สถาปัตยกรรม HCE มอบความปลอดภัยที่สำคัญเพียงข้อเดียว เนื่องจากบริการของคุณได้รับการปกป้องโดยสิทธิ์ของระบบ BIND_NFC_SERVICE จึงมีเฉพาะระบบปฏิบัติการเท่านั้นที่เชื่อมโยงและสื่อสารกับบริการของคุณได้ วิธีนี้ช่วยให้มั่นใจได้ว่า APDU ที่คุณได้รับคือ APDU ที่ระบบปฏิบัติการได้รับจากตัวควบคุม NFC และ APDU ที่คุณส่งกลับจะไปที่ระบบปฏิบัติการเท่านั้น ซึ่งจะส่งต่อ APDU ไปยังตัวควบคุม NFC โดยตรง

ข้อกังวลสุดท้ายที่เหลือคือแหล่งที่มาของข้อมูลที่คุณส่งจากแอปไปยังเครื่องอ่าน NFC ข้อมูลนี้มีการแยกออกจากการออกแบบ HCE โดยเจตนา โดยไม่สนใจว่าข้อมูลมาจากที่ใด เพียงแต่ตรวจสอบว่าข้อมูลได้รับการส่งไปยังตัวควบคุม NFC และไปยังเครื่องอ่าน NFC อย่างปลอดภัย

หากต้องการจัดเก็บและเรียกข้อมูลที่ต้องการส่งจากบริการ HCE อย่างปลอดภัย คุณอาจใช้แซนด์บ็อกซ์แอปพลิเคชันของ Android ซึ่งจะแยกข้อมูลของแอปคุณออกจากแอปอื่นๆ อ่านรายละเอียดเพิ่มเติมเกี่ยวกับความปลอดภัยของ Android ได้ที่เคล็ดลับด้านความปลอดภัย

พารามิเตอร์และรายละเอียดโปรโตคอล

ส่วนนี้จะเป็นประโยชน์สำหรับนักพัฒนาซอฟต์แวร์ที่ต้องการทำความเข้าใจพารามิเตอร์โปรโตคอลที่อุปกรณ์ HCE ใช้ในระหว่างระยะการป้องกันการเกิดข้อขัดแย้งและระยะการเปิดใช้งานของโปรโตคอล NFC ซึ่งช่วยให้สร้างโครงสร้างพื้นฐานสำหรับผู้อ่านที่ เข้ากันได้กับอุปกรณ์ Android HCE

การป้องกันและการเปิดใช้งานโปรโตคอล Nfc-A (ISO/IEC 14443 ประเภท A)

ในการเปิดใช้งานโปรโตคอล Nfc-A ระบบจะแลกเปลี่ยนเฟรมหลายเฟรม

ในส่วนแรกของการแลกเปลี่ยน อุปกรณ์ HCE จะแสดง UID ของตน โดยควรถือว่าอุปกรณ์ HCE มี UID แบบสุ่ม ซึ่งหมายความว่าทุกครั้งที่แตะ UID ที่แสดงต่อผู้อ่านจะเป็น UID ที่สร้างขึ้นแบบสุ่ม ด้วยเหตุนี้ เครื่องอ่าน NFC จึงไม่ควรใช้ UID ของอุปกรณ์ HCE เป็นรูปแบบการตรวจสอบสิทธิ์หรือการระบุตัวตน

จากนั้นเครื่องอ่าน NFC จะเลือกอุปกรณ์ HCE ได้โดยส่งSEL_REQคำสั่ง การตอบสนองของ SEL_RES ของอุปกรณ์ HCE มีการตั้งค่าบิตที่ 6 (0x20) เป็นอย่างน้อย ซึ่งบ่งชี้ว่าอุปกรณ์รองรับ ISO-DEP โปรดทราบว่าคุณอาจตั้งค่าบิตอื่นๆ ใน SEL_RES ไว้ด้วยได้ เช่น การรองรับโปรโตคอล NFC-DEP (p2p) ด้วย เนื่องจากอาจมีการตั้งค่าบิตอื่นๆ ตัวอ่านที่ต้องการโต้ตอบกับอุปกรณ์ HCE ควรตรวจสอบบิตที่ 6 เท่านั้น และไม่เปรียบเทียบ SEL_RES ที่สมบูรณ์กับค่า 0x20

การเปิดใช้งาน ISO-DEP

หลังจากเปิดใช้งานโปรโตคอล Nfc-A แล้ว โปรแกรมอ่าน NFC จะเริ่มต้นการเปิดใช้งานโปรโตคอล ISO-DEP โดยจะส่งคําสั่ง RATS (คําขอคำตอบเพื่อเลือก) ตัวควบคุม NFC จะสร้างการตอบสนอง RATS ซึ่งก็คือ ATS โดยที่บริการ HCE จะกำหนดค่า ATS ไม่ได้ อย่างไรก็ตาม การใช้งาน HCE ต้องเป็นไปตามข้อกำหนดของ NFC Forum สําหรับการตอบกลับ ATS เพื่อให้เครื่องอ่าน NFC ตั้งค่าพารามิเตอร์เหล่านี้ได้ตามข้อกําหนดของ NFC Forum สําหรับอุปกรณ์ HCE

ส่วนด้านล่างแสดงรายละเอียดเพิ่มเติมเกี่ยวกับแต่ละไบต์ของคำตอบ ATS ที่ได้จากตัวควบคุม NFC ในอุปกรณ์ HCE

  • TL: ความยาวของคำตอบ ATS ต้องระบุความยาวไม่เกิน 20 ไบต์
  • T0: ต้องตั้งค่าบิต 5, 6 และ 7 ในอุปกรณ์ HCE ทั้งหมด ซึ่งบ่งบอกว่า TA(1), TB(1) และ TC(1) รวมอยู่ในคำตอบ ATS บิตที่ 1 ถึง 4 ระบุ FSCI ซึ่งเข้ารหัสขนาดเฟรมสูงสุด ในอุปกรณ์ HCE ค่า FSCI ต้องอยู่ในช่วง 0-8 ชั่วโมง
  • T(A)1: กําหนดอัตราบิตระหว่างโปรแกรมอ่านกับโปรแกรมจําลอง และระบุว่าอัตราบิตดังกล่าวจะเป็นแบบไม่สมมาตรได้หรือไม่ ไม่มีข้อกำหนดหรือการรับประกันอัตราบิตสำหรับอุปกรณ์ HCE
  • T(B)1: บิตที่ 1 ถึง 4 ระบุจำนวนเต็มสำหรับเวลาป้องกันเฟรมเริ่มต้น (SFGI) ในอุปกรณ์ HCE ค่า SFGI ต้องน้อยกว่าหรือเท่ากับ 8 ชั่วโมง บิตที่ 5 ถึง 8 ระบุจำนวนเต็มของเวลาที่ใช้ในการรอเฟรม (FWI) และเข้ารหัสเวลาที่ใช้ในการรอเฟรม (FWT) ในอุปกรณ์ HCE ค่า FWI ต้องน้อยกว่าหรือเท่ากับ 8 ชั่วโมง
  • T(C)1: บิต 5 ระบุการรองรับ "ฟีเจอร์โปรโตคอลขั้นสูง" อุปกรณ์ HCE อาจรองรับหรือไม่รองรับ "ฟีเจอร์โปรโตคอลขั้นสูง" บิต 2 ระบุการรองรับ DID อุปกรณ์ HCE อาจรองรับ DID หรือไม่ก็ได้ บิตที่ 1 หมายถึงการรองรับ NAD อุปกรณ์ HCE ต้องไม่รองรับ NAD และตั้งค่าบิต 1 เป็น 0
  • ไบต์ที่ผ่านมา: อุปกรณ์ HCE อาจแสดงผลไบต์ที่ผ่านมาได้สูงสุด 15 รายการ เครื่องอ่าน NFC ที่ต้องการโต้ตอบกับบริการ HCE ไม่ควรคาดเดาเนื้อหาของไบต์ที่ผ่านมาหรือสถานะของไบต์เหล่านั้น

โปรดทราบว่าอุปกรณ์ HCE จำนวนมากมีแนวโน้มที่จะเป็นไปตามข้อกำหนดของโปรโตคอลที่เครือข่ายการชำระเงินที่รวมอยู่ใน EMVCo ได้ระบุไว้ในข้อกำหนดเฉพาะ "โปรโตคอลการสื่อสารแบบไม่ต้องสัมผัส" โดยเฉพาะอย่างยิ่ง:

  • FSCI ใน T0 ต้องอยู่ระหว่าง 2-8 ชั่วโมง
  • ต้องตั้งค่า T(A)1 เป็น 0x80 ซึ่งระบุว่าระบบรองรับเฉพาะอัตราบิต 106 กิโลบิต/วินาที และระบบไม่รองรับอัตราบิตแบบไม่สมมาตรระหว่างโปรแกรมอ่านและโปรแกรมจำลอง
  • FWI ใน T(B)1 ต้องน้อยกว่าหรือเท่ากับ 7 ชั่วโมง

การแลกเปลี่ยนข้อมูล APDU

ดังที่กล่าวไว้ก่อนหน้านี้ การติดตั้งใช้งาน HCE รองรับเฉพาะช่องทางตรรกะเดียวเท่านั้น การพยายามเลือกแอปพลิเคชันในช่องทางตรรกะที่แตกต่างกันจะใช้ไม่ได้ในอุปกรณ์ HCE