อุปกรณ์ Android จำนวนมากที่ให้บริการฟังก์ชัน NFC รองรับการจําลองบัตร NFC อยู่แล้ว ในกรณีส่วนใหญ่ ชิปแยกต่างหากในอุปกรณ์จะจำลองบัตร ซึ่งเรียกว่าองค์ประกอบที่ปลอดภัย ซิมการ์ดจำนวนมากที่ผู้ให้บริการเครือข่ายไร้สายมีให้ก็มีองค์ประกอบที่ปลอดภัยด้วย
Android 4.4 ขึ้นไปมีวิธีการจำลองบัตรเพิ่มเติมที่ไม่เกี่ยวข้องกับองค์ประกอบที่ปลอดภัย ซึ่งเรียกว่าการจำลองบัตรแบบโฮสต์ ซึ่งช่วยให้แอปพลิเคชัน Android จำลองบัตรและสื่อสารกับเครื่องอ่าน NFC ได้โดยตรง หัวข้อนี้จะอธิบายวิธีการทำงานของโปรแกรมจำลองการ์ดแบบโฮสต์ (HCE) ใน Android และวิธีพัฒนาแอปที่จำลองการ์ด NFC โดยใช้เทคนิคนี้
การจําลองบัตรด้วยองค์ประกอบความปลอดภัย
เมื่อมีการจำลองบัตร NFC โดยใช้องค์ประกอบความปลอดภัย ระบบจะจัดสรรบัตรที่จะจําลองลงในองค์ประกอบความปลอดภัยบนอุปกรณ์ผ่านแอปพลิเคชัน Android จากนั้นเมื่อผู้ใช้ถืออุปกรณ์เหนือเครื่องอ่าน NFC ตัวควบคุม NFC ในอุปกรณ์จะส่งข้อมูลทั้งหมดจากเครื่องอ่านไปยังองค์ประกอบที่ปลอดภัยโดยตรง รูปที่ 1 แสดงแนวคิดนี้
องค์ประกอบที่ปลอดภัยจะสื่อสารกับเครื่องชำระเงิน NFC โดยที่แอปพลิเคชัน Android จะไม่เกี่ยวข้องในธุรกรรม หลังจากธุรกรรมเสร็จสมบูรณ์แล้ว แอปพลิเคชัน Android จะค้นหาสถานะธุรกรรมจากองค์ประกอบที่ปลอดภัยได้โดยตรงและแจ้งให้ผู้ใช้ทราบ
โปรแกรมจำลองการ์ดแบบโฮสต์
เมื่อจําลองบัตร NFC โดยใช้การจําลองบัตรที่อิงตามโฮสต์ ระบบจะส่งข้อมูลไปยัง CPU ของโฮสต์โดยตรงแทนที่จะส่งไปยังองค์ประกอบที่ปลอดภัย รูปที่ 2 แสดงวิธีการทำงานของโปรแกรมจำลองการ์ดแบบโฮสต์
บัตรและโปรโตคอล NFC ที่รองรับ
มาตรฐาน 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 สำหรับ 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()
ของคลาสด้วยอาร์กิวเมนต์ที่ระบุว่าเกิดเหตุการณ์ใดขึ้น
หากใช้โครงสร้างพื้นฐานเครื่องอ่านที่มีอยู่ คุณต้องติดตั้งใช้งานโปรโตคอลระดับแอปพลิเคชันที่มีอยู่ซึ่งเครื่องอ่านคาดหวังในบริการ HCE
หากกำลังติดตั้งใช้งานโครงสร้างพื้นฐานเครื่องอ่านแบบใหม่ที่คุณควบคุมด้วย คุณก็กำหนดโปรโตคอลและลําดับ APDU ของคุณเองได้ พยายามจำกัดจำนวน APDU และขนาดของข้อมูลที่แลกเปลี่ยน: วิธีนี้ช่วยให้ผู้ใช้ต้องถืออุปกรณ์เหนือเครื่องอ่าน NFC เพียงระยะเวลาสั้นๆ ขอบเขตบนที่เหมาะสมคือข้อมูลประมาณ 1 KB ซึ่งโดยปกติจะแลกเปลี่ยนได้ภายใน 300 ms
การประกาศไฟล์ Manifest ของบริการและการลงทะเบียน AID
คุณต้องประกาศบริการในไฟล์ Manifest ตามปกติ แต่ต้องเพิ่มข้อมูลบางอย่างในการประกาศบริการด้วย
หากต้องการบอกแพลตฟอร์มว่าเป็นบริการ HCE ที่ใช้
HostApduService
อินเทอร์เฟซ ให้เพิ่มตัวกรอง Intent สําหรับการดำเนินการSERVICE_INTERFACE
ลงในประกาศบริการหากต้องการบอกแพลตฟอร์มว่าบริการนี้ขอกลุ่ม AID ใด ให้ใส่แท็ก
SERVICE_META_DATA
<meta-data>
ในการประกาศบริการ ซึ่งชี้ไปยังแหล่งข้อมูล XML ที่มีข้อมูลเพิ่มเติมเกี่ยวกับบริการ HCEตั้งค่าแอตทริบิวต์
android:exported
เป็นtrue
และกำหนดสิทธิ์android.permission.BIND_NFC_SERVICE
ในการประกาศบริการ ตัวเลือกแรกช่วยให้แอปพลิเคชันภายนอกสามารถเชื่อมโยงกับบริการได้ จากนั้นนโยบายนี้จะบังคับให้มีเพียงแอปพลิเคชันภายนอกที่มีสิทธิ์android.permission.BIND_NFC_SERVICE
เท่านั้นที่จะสามารถเชื่อมโยงกับบริการของคุณได้ เนื่องจากandroid.permission.BIND_NFC_SERVICE
เป็นสิทธิ์ของระบบ การดำเนินการนี้จึงบังคับให้เฉพาะระบบปฏิบัติการ Android เท่านั้นที่เชื่อมโยงกับบริการของคุณได้
ต่อไปนี้เป็นตัวอย่างการประกาศในไฟล์ 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 จะกำหนดบริการที่จะเรียกใช้โดยใช้ขั้นตอนต่อไปนี้
- หากแอป Wallet เริ่มต้นที่ผู้ใช้เลือกลงทะเบียน AID แล้ว ระบบจะเรียกใช้แอปนั้น
- หากแอป Wallet เริ่มต้นไม่ได้ลงทะเบียน AID ระบบจะเรียกใช้บริการที่ลงทะเบียน AID ไว้
- หากมีบริการมากกว่า 1 บริการที่ลงทะเบียน AID แล้ว Android จะถามผู้ใช้ว่าต้องการเรียกใช้บริการใด
ค่ากําหนดบริการที่ทำงานอยู่เบื้องหน้า
แอปที่ทำงานอยู่เบื้องหน้าสามารถเรียกใช้ setPreferredService
เพื่อระบุบริการจําลองบัตรที่ต้องการขณะที่กิจกรรมหนึ่งๆ อยู่เบื้องหน้า ค่ากําหนดแอปที่ทำงานอยู่เบื้องหน้านี้จะลบล้างการแก้ไขข้อขัดแย้งของ AID
แนวทางปฏิบัตินี้แนะนําเมื่อแอปคาดการณ์ว่าผู้ใช้อาจใช้การจําลองบัตร NFC
Android 13 ขึ้นไป
หากต้องการให้พอดีกับรายการตัวเลือกการชำระเงินเริ่มต้นใน UI การตั้งค่ามากขึ้น ให้ปรับข้อกำหนดแบนเนอร์เป็นไอคอนสี่เหลี่ยมจัตุรัส โดยควรเหมือนกับการออกแบบไอคอนตัวเปิดแอป การปรับนี้จะช่วยเพิ่มความสอดคล้องและทำให้ดูสะอาดตามากขึ้น
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>
แอปพลิเคชัน Wallet
Android 15 ขึ้นไปมีบทบาทของแอป Wallet เริ่มต้นที่ผู้ใช้สามารถเลือกได้ โดยไปที่การตั้งค่า > แอป > แอปเริ่มต้น ข้อมูลนี้กำหนดแอปพลิเคชันเวิล์ดมาสเตอร์เริ่มต้นที่จะเรียกใช้เมื่อแตะเครื่องชำระเงิน Android จะถือว่าบริการ HCE ที่ประกาศกลุ่ม AID ที่มีหมวดหมู่การชำระเงินเป็นแอปพลิเคชันเวิล์ดเทรด
ตรวจสอบว่าแอปของคุณเป็นแอป Wallet เริ่มต้นหรือไม่
แอปสามารถตรวจสอบว่าเป็นแอป Wallet เริ่มต้นหรือไม่ได้โดยส่ง RoleManager.ROLE_WALLET
ไปยัง RoleManager.isRoleHeld()
หากแอปของคุณไม่ใช่แอปเริ่มต้น คุณสามารถขอบทบาทกระเป๋าเงินเริ่มต้นได้โดยส่ง RoleManager.ROLE_WALLET
ไปยัง RoleManager.createRequestRoleIntent()
ชิ้นงานที่จําเป็นสําหรับแอปพลิเคชันเวิล์ต
แอปพลิเคชันกระเป๋าเงิน HCE ต้องมีแบนเนอร์บริการเพื่อให้ผู้ใช้ได้รับประสบการณ์การใช้งานที่ดึงดูดสายตามากขึ้น
โหมดสังเกตการณ์
Android 15 เปิดตัวฟีเจอร์โหมดสังเกตการณ์ เมื่อเปิดใช้ โหมดสังเกตการณ์จะอนุญาตให้อุปกรณ์สังเกตการณ์ลูปการสำรวจ NFC และส่งการแจ้งเตือนเกี่ยวกับลูปดังกล่าวไปยังคอมโพเนนต์ HostApduService
ที่เหมาะสมเพื่อให้เตรียมพร้อมที่จะโต้ตอบกับเครื่องชำระเงิน NFC เครื่องหนึ่งๆ HostApduService
สามารถทำให้อุปกรณ์เข้าสู่โหมดสังเกตการณ์ได้โดยส่ง true
ไปยัง setObserveModeEnabled()
ซึ่งจะสั่งให้สแต็ก NFC ไม่อนุญาตให้ทำธุรกรรม NFC และสังเกตการณ์ลูปการสำรวจแบบพาสซีฟแทน
ตัวกรองลูปการสำรวจ
คุณสามารถลงทะเบียนตัวกรองลูปการโหวตสําหรับ HostApduService
ได้โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้
registerPollingLoopFilterForService()
สําหรับตัวกรองที่ต้องตรงกับกรอบเวลาการสำรวจทุกประการregisterPollingLoopPatternFilterForService()
สําหรับตัวกรองที่ตรงกับนิพจน์ทั่วไปกับเฟรมการโหวต
เมื่อตัวกรองลูปการสำรวจตรงกับเฟรมการสำรวจที่ไม่เป็นมาตรฐาน สแต็ก NFC จะกำหนดเส้นทางเฟรมการสำรวจเหล่านั้นไปยัง HostApduService
ที่เกี่ยวข้องโดยเรียกใช้เมธอด processPollingFrames()
ของ HostApduService
ซึ่งจะช่วยให้บริการดำเนินการตามขั้นตอนที่จำเป็นเพื่อให้มั่นใจว่าผู้ใช้พร้อมทำธุรกรรมและตั้งใจที่จะทำเช่นนั้น เช่น การตรวจสอบสิทธิ์ผู้ใช้ หากเครื่องอ่าน NFC ใช้เฉพาะเฟรมมาตรฐานในลูปการสำรวจ สแต็ก NFC จะกำหนดเส้นทางเฟรมการสำรวจเหล่านั้นไปยังบริการที่ทำงานอยู่เบื้องหน้าที่ต้องการ หากบริการดังกล่าวทำงานอยู่เบื้องหน้า หรือไปยังผู้ถือบทบาทเริ่มต้นของ Wallet
การแจ้งเตือนเฟรมการโหวตยังรวมถึงการวัดความแรงของสัญญาณเฉพาะผู้ให้บริการที่คุณสามารถเรียกดูได้โดยเรียกใช้ getVendorSpecificGain()
ผู้ให้บริการสามารถระบุการวัดโดยใช้มาตราส่วนของตนเองได้ ตราบใดที่ข้อมูลดังกล่าวอยู่ภายในไบต์เดียว
ตอบสนองต่อลูปการโหวตและออกจากโหมดสังเกตการณ์
เมื่อบริการพร้อมทำธุรกรรมแล้ว บริการจะออกจากโหมดสังเกตการณ์ได้โดยส่ง false
ไปยัง setObserveModeEnabled()
จากนั้นสแต็ก NFC จะอนุญาตให้ทำธุรกรรมต่อ
คอมโพเนนต์ HostApduService
สามารถระบุว่าควรเปิดใช้โหมดสังเกตการณ์ทุกครั้งที่เป็นบริการการชำระเงินที่ต้องการได้โดยการตั้งค่า shouldDefaultToObserveMode
เป็น true
ในไฟล์ Manifest หรือเรียกใช้ CardEmulation.setShouldDefaultToObserveModeForService()
คอมโพเนนต์ HostApduService
และ OffHostApduService
ยังระบุได้ด้วยว่าตัวกรองลูปการโหวตที่ตรงกับเฟรมลูปการโหวตที่ได้รับควรปิดใช้โหมดสังเกตการณ์โดยอัตโนมัติและอนุญาตให้ธุรกรรมดำเนินการต่อโดยการตั้งค่า autoTransact
เป็น true
ในประกาศ PollingLoopFilter
ในไฟล์ Manifest
ค่ากําหนดบริการที่ทำงานอยู่เบื้องหน้า
แอปที่ทำงานอยู่เบื้องหน้าสามารถเรียกใช้ setPreferredService
เพื่อระบุบริการจําลองบัตรที่ต้องการขณะที่กิจกรรมหนึ่งๆ อยู่เบื้องหน้า ค่ากําหนดของแอปที่ทำงานอยู่เบื้องหน้านี้จะลบล้างสถานะโหมดสังเกตการณ์ของอุปกรณ์ซึ่งสอดคล้องกับค่า shouldDefaultToObserveMode
สําหรับบริการหนึ่งๆ ซึ่งสามารถตั้งค่าได้ 1 ใน 2 วิธีต่อไปนี้
- การตั้งค่าสถานะของ
shouldDefaultToObserveMode
ในไฟล์ Manifest สําหรับบริการนั้น - การเรียกใช้
CardEmulation.setShouldDefaultToObserveModeForService()
ด้วยบริการและสถานะที่เกี่ยวข้อง
ลักษณะการทํางานของหน้าจอปิดและหน้าจอล็อก
ลักษณะการทํางานของบริการ HCE จะแตกต่างกันไปตามเวอร์ชัน Android ที่ใช้งานในอุปกรณ์
Android 15 ขึ้นไป
หากแอป Wallet เริ่มต้นเปิดโหมดสังเกตการณ์ในอุปกรณ์ที่รองรับ แอปนั้นจะลบล้างลักษณะการเลิกล็อกและปิดหน้าจอ เนื่องจากแอปดังกล่าวควบคุมเวลาที่ธุรกรรมจะดำเนินการได้ แอป Wallet บางแอปอาจกำหนดให้อุปกรณ์ปลดล็อกก่อนจึงจะดำเนินการธุรกรรมได้ หากโหมดสังเกตการณ์ไม่พบรูปแบบการวนลูปการสำรวจที่ระบุได้
เราขอแนะนำให้นักพัฒนาแอปทำงานร่วมกับอุปกรณ์อ่านเพื่อส่งรูปแบบลูปการสำรวจที่ระบุตัวตนได้ และลงทะเบียนเพื่อจัดการรูปแบบเหล่านั้นจากแอป
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 และต่ำกว่า แต่จะใช้งานได้ก็ต่อเมื่อปิด Secure NFC เท่านั้น กล่าวคือ หากเปิด Secure 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 จะมีเส้นทางเริ่มต้นสำหรับ APDU ด้วย เมื่อไม่พบ AID ในตารางการกําหนดเส้นทาง ระบบจะใช้เส้นทางเริ่มต้น แม้ว่าการตั้งค่านี้อาจแตกต่างกันไปในแต่ละอุปกรณ์ แต่อุปกรณ์ Android จะต้องตรวจสอบว่า AID ที่แอปของคุณลงทะเบียนได้รับการส่งไปยังโฮสต์อย่างถูกต้อง
แอปพลิเคชัน Android ที่ใช้บริการ HCE หรือใช้องค์ประกอบที่ปลอดภัยไม่ต้องกังวลเกี่ยวกับการกำหนดค่าตารางเส้นทาง เนื่องจาก Android จะจัดการให้โดยอัตโนมัติ Android เพียงต้องทราบว่า AID ใดที่บริการ HCE จัดการได้และ AID ใดที่องค์ประกอบที่ปลอดภัยจัดการได้ ระบบจะกําหนดค่าตารางการกําหนดเส้นทางโดยอัตโนมัติตามบริการที่ติดตั้งและบริการที่ผู้ใช้กําหนดค่าไว้
ส่วนต่อไปนี้จะอธิบายวิธีประกาศ 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