بسیاری از دستگاههای مجهز به Android که عملکرد NFC را ارائه میدهند، از شبیهسازی کارت NFC پشتیبانی میکنند. در بیشتر موارد، کارت توسط یک تراشه جداگانه در دستگاه شبیه سازی می شود که عنصر امن نامیده می شود. بسیاری از سیم کارت های ارائه شده توسط اپراتورهای بی سیم نیز حاوی یک عنصر امن هستند.
Android نسخه 4.4 و بالاتر یک روش اضافی برای شبیهسازی کارت ارائه میکند که شامل یک عنصر امن نیست، به نام شبیهسازی کارت مبتنی بر میزبان . این به هر برنامه اندرویدی اجازه میدهد کارت را شبیهسازی کند و مستقیماً با خواننده NFC صحبت کند. این مبحث توضیح میدهد که شبیهسازی کارت مبتنی بر میزبان (HCE) در اندروید چگونه کار میکند و چگونه میتوانید برنامهای ایجاد کنید که کارت NFC را با استفاده از این تکنیک شبیهسازی کند.
شبیه سازی کارت با یک عنصر امن
وقتی شبیهسازی کارت NFC با استفاده از یک عنصر امن ارائه میشود، کارتی که باید شبیهسازی شود از طریق یک برنامه Android در عنصر امن روی دستگاه ارائه میشود. سپس، هنگامی که کاربر دستگاه را روی یک ترمینال NFC نگه میدارد، کنترلکننده NFC در دستگاه تمام دادهها را مستقیماً از خواننده به عنصر امن هدایت میکند. شکل 1 این مفهوم را نشان می دهد:
خود عنصر امن ارتباط با ترمینال NFC را انجام می دهد و هیچ برنامه اندرویدی در تراکنش دخیل نیست. پس از تکمیل تراکنش، یک برنامه اندرویدی میتواند عنصر امن را مستقیماً برای وضعیت تراکنش جستجو کرده و به کاربر اطلاع دهد.
شبیه سازی کارت مبتنی بر میزبان
هنگامی که یک کارت NFC با استفاده از شبیه سازی کارت مبتنی بر میزبان شبیه سازی می شود، داده ها به جای اینکه به یک عنصر امن هدایت شوند، مستقیماً به CPU میزبان هدایت می شوند. شکل 2 نحوه عملکرد شبیه سازی کارت مبتنی بر میزبان را نشان می دهد:
کارت ها و پروتکل های NFC پشتیبانی می شود
استانداردهای NFC از پروتکلهای مختلف پشتیبانی میکنند و انواع مختلفی از کارتها وجود دارد که میتوانید از آنها تقلید کنید.
اندروید 4.4 و بالاتر از چندین پروتکل که امروزه در بازار رایج هستند پشتیبانی می کند. بسیاری از کارت های بدون تماس موجود در حال حاضر بر اساس این پروتکل ها هستند، مانند کارت های پرداخت بدون تماس. این پروتکلها همچنین توسط بسیاری از خوانندههای NFC در بازار امروز پشتیبانی میشوند، از جمله دستگاههای Android NFC که خود به عنوان خواننده عمل میکنند (به کلاس IsoDep
مراجعه کنید). این به شما امکان میدهد یک راهحل NFC سرتاسر را در اطراف HCE تنها با استفاده از دستگاههای مجهز به Android بسازید و به کار ببرید.
به طور خاص، Android 4.4 و بالاتر از کارتهای شبیهسازی پشتیبانی میکند که بر اساس مشخصات ISO-DEP NFC-Forum (بر اساس ISO/IEC 14443-4) و واحدهای داده پروتکل برنامه (APDUs) پردازش میشوند که در ISO/IEC 7816-4 تعریف شدهاند. مشخصات Android تقلید ISO-DEP را فقط در بالای فناوری Nfc-A (ISO/IEC 14443-3 Type A) الزامی میکند. پشتیبانی از فناوری Nfc-B (ISO/IEC 14443-4 Type B) اختیاری است. شکل 3 لایه بندی تمامی این مشخصات را نشان می دهد.
خدمات HCE
معماری HCE در اندروید مبتنی بر مؤلفههای Service
Android (معروف به خدمات HCE ) است. یکی از مزایای کلیدی یک سرویس این است که می تواند در پس زمینه بدون هیچ رابط کاربری اجرا شود. این یک تناسب طبیعی برای بسیاری از برنامههای کاربردی HCE است، مانند کارتهای وفاداری یا حملونقل، که کاربر برای استفاده از آنها نیازی به راهاندازی برنامه ندارد. درعوض، ضربه زدن روی دستگاه در مقابل خواننده NFC، سرویس صحیح را در صورتی که از قبل اجرا نشده باشد، شروع میکند و تراکنش را در پسزمینه اجرا میکند. البته، شما آزاد هستید که در صورت لزوم رابط کاربری اضافی (مانند اعلان های کاربر) را از سرویس خود راه اندازی کنید.
انتخاب خدمات
هنگامی که کاربر دستگاهی را به یک خواننده NFC میزند، سیستم Android باید بداند که خواننده NFC میخواهد با کدام سرویس HCE ارتباط برقرار کند. مشخصات ISO/IEC 7816-4 راهی را برای انتخاب برنامهها تعریف میکند که حول یک شناسه برنامه (AID) متمرکز شده است. یک AID حداکثر از 16 بایت تشکیل شده است. اگر کارتهایی را برای زیرساختهای خواننده NFC موجود تقلید میکنید، AIDهایی که آن خوانندگان به دنبال آن هستند معمولاً شناخته شده هستند و به صورت عمومی ثبت شدهاند (به عنوان مثال، AIDهای شبکههای پرداخت مانند Visa و MasterCard).
اگر میخواهید زیرساختهای خواننده جدید را برای برنامه خود مستقر کنید، باید ایدز خود را ثبت کنید. روش ثبت ایدز در مشخصات ISO/IEC 7816-5 تعریف شده است. توصیه می کنیم اگر یک برنامه HCE را برای اندروید اجرا می کنید، یک AID مطابق با 7816-5 ثبت کنید، زیرا از برخورد با سایر برنامه ها جلوگیری می کند.
گروه های ایدز
در برخی موارد، یک سرویس HCE ممکن است نیاز به ثبت چندین AID داشته باشد و به عنوان کنترل کننده پیش فرض برای همه AID ها تنظیم شود تا برنامه خاصی را پیاده سازی کند. برخی از ایدزهای گروهی که به سرویس دیگری می روند، پشتیبانی نمی شوند.
فهرستی از ایدزهایی که در کنار هم نگهداری می شوند، گروه AID نامیده می شود. برای همه ایدزهای یک گروه AID، Android یکی از موارد زیر را تضمین می کند:
- همه ایدزهای گروه به این سرویس HCE هدایت می شوند.
- هیچ AID در گروه به این سرویس HCE هدایت نمی شود (به عنوان مثال، زیرا کاربر سرویس دیگری را ترجیح می دهد که یک یا چند AID در گروه شما نیز درخواست کرده است).
به عبارت دیگر، هیچ حالتی وجود ندارد که در آن برخی از ایدزهای گروه به یک سرویس HCE و برخی به سرویس دیگر هدایت شوند.
گروه ها و دسته های کمک
شما می توانید هر گروه AID را با یک دسته مرتبط کنید. این به اندروید اجازه میدهد تا سرویسهای HCE را بر اساس دستهبندی گروهبندی کند و به نوبه خود به کاربر اجازه میدهد تا پیشفرضها را در سطح دسته به جای سطح AID تنظیم کند. از ذکر ایدز در هر قسمتی که کاربر رو به رو است از برنامه خود خودداری کنید، زیرا برای کاربر معمولی معنایی ندارد.
اندروید 4.4 و بالاتر از دو دسته پشتیبانی می کند:
-
CATEGORY_PAYMENT
(شامل برنامههای پرداخت استاندارد صنعتی) -
CATEGORY_OTHER
(برای همه برنامههای دیگر HCE)
یک سرویس HCE را اجرا کنید
برای شبیهسازی یک کارت NFC با استفاده از شبیهسازی کارت مبتنی بر میزبان، باید یک مؤلفه Service
ایجاد کنید که تراکنشهای NFC را مدیریت کند.
پشتیبانی HCE را بررسی کنید
برنامه شما می تواند با بررسی ویژگی FEATURE_NFC_HOST_CARD_EMULATION
بررسی کند که آیا دستگاهی از HCE پشتیبانی می کند یا خیر. از تگ <uses-feature>
در مانیفست برنامه خود استفاده کنید تا اعلام کنید که برنامه شما از ویژگی HCE استفاده می کند و اینکه آیا برای عملکرد برنامه لازم است یا خیر.
اجرای خدمات
اندروید 4.4 و بالاتر یک کلاس Service
راحت ارائه میکند که میتوانید از آن به عنوان پایهای برای اجرای یک سرویس HCE استفاده کنید: کلاس HostApduService
.
مرحله اول گسترش HostApduService
است، همانطور که در نمونه کد زیر نشان داده شده است:
کاتلین
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) را به سرویس شما ارسال میکند، فراخوانی میشود. APDU ها در مشخصات ISO/IEC 7816-4 تعریف شده اند. APDU ها بسته های سطح برنامه هستند که بین خواننده NFC و سرویس HCE شما مبادله می شوند. آن پروتکل در سطح برنامه نیمه دوطرفه است: خواننده NFC یک دستور APDU را برای شما ارسال می کند و منتظر می ماند تا در ازای آن یک APDU پاسخ ارسال کنید.
همانطور که قبلا ذکر شد، Android از AID برای تعیین اینکه خواننده می خواهد با کدام سرویس HCE صحبت کند، استفاده می کند. به طور معمول، اولین APDU که یک خواننده NFC به دستگاه شما ارسال می کند یک SELECT AID
APDU است. این APDU حاوی کمکی است که خواننده می خواهد با آن صحبت کند. Android آن AID را از APDU استخراج می کند، آن را به یک سرویس HCE حل می کند و سپس آن APDU را به سرویس حل شده ارسال می کند.
میتوانید با برگرداندن بایتهای APDU پاسخ از processCommandApdu()
یک APDU پاسخ ارسال کنید. توجه داشته باشید که این روش در رشته اصلی برنامه شما فراخوانی می شود که نباید آن را مسدود کنید. اگر نمی توانید بلافاصله یک APDU پاسخ را محاسبه و برگردانید، null را برگردانید. سپس می توانید کارهای لازم را روی رشته دیگری انجام دهید و از متد sendResponseApdu()
که در کلاس HostApduService
تعریف شده است استفاده کنید تا پس از اتمام کار، پاسخ را ارسال کنید.
Android APDU های جدید را از خواننده به سرویس شما ارسال می کند تا زمانی که یکی از موارد زیر رخ دهد:
- خواننده NFC
SELECT AID
APDU دیگری را ارسال می کند که سیستم عامل آن را به سرویس دیگری حل می کند. - پیوند NFC بین خواننده NFC و دستگاه شما خراب است.
در هر دوی این موارد، پیاده سازی onDeactivated()
کلاس شما با یک آرگومان فراخوانی می شود که نشان می دهد کدام یک از این دو اتفاق افتاده است.
اگر با زیرساخت خواننده موجود کار می کنید، باید پروتکل موجود در سطح برنامه را که خوانندگان انتظار دارند در سرویس HCE خود پیاده سازی کنید.
اگر زیرساختهای خواننده جدیدی را که کنترل میکنید، مستقر میکنید، میتوانید پروتکل و دنباله APDU خود را تعریف کنید. سعی کنید مقدار APDU و اندازه دادههای مورد تبادل را محدود کنید: این کار باعث میشود کاربران شما فقط برای مدت کوتاهی دستگاه خود را روی خواننده NFC نگه دارند. یک کران بالای معقول حدود 1 کیلوبایت داده است که معمولاً می تواند در عرض 300 میلی ثانیه مبادله شود.
اعلامیه مانیفست خدمات و ثبت AID
طبق معمول باید سرویس خود را در مانیفست اعلام کنید، اما باید چند قطعه اضافی را نیز به اعلان سرویس اضافه کنید:
برای اینکه به پلتفرم بگویید یک سرویس HCE است که رابط
HostApduService
را اجرا می کند، یک فیلتر هدف برای عملکردSERVICE_INTERFACE
به اعلان سرویس خود اضافه کنید.برای اینکه به پلتفرم بگویید کدام گروه های ایدز توسط این سرویس درخواست می شوند، یک تگ
<meta-data>
SERVICE_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 اختصاصی است:
<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>
باشد که حاوی توضیحات کاربرپسندی از سرویس است که میتوانید در رابط کاربری برنامه نشان دهید. میتوانید از ویژگی requireDeviceUnlock
برای تعیین قفل دستگاه قبل از فراخوانی این سرویس برای مدیریت APDUها استفاده کنید.
<host-apdu-service>
باید دارای یک یا چند تگ <aid-group>
باشد. هر تگ <aid-group>
باید موارد زیر را انجام دهد:
- حاوی ویژگی
android:description
که حاوی توضیحات کاربرپسند گروه AID است که برای نمایش در رابط کاربری مناسب است. - ویژگی
android:category
آن را برای نشان دادن دستهای که گروه AID به آن تعلق دارد، تنظیم کنید، مانند ثابتهای رشتهای که توسطCATEGORY_PAYMENT
یاCATEGORY_OTHER
تعریف شدهاند. - حاوی یک یا چند تگ
<aid-filter>
که هر کدام شامل یک AID می باشد. AID را در قالب هگزادسیمال مشخص کنید و مطمئن شوید که دارای تعداد زوجی از کاراکترها باشد.
برنامه شما همچنین برای ثبت نام به عنوان یک سرویس HCE باید مجوز NFC
را داشته باشد.
حل تعارض ایدز
چندین مؤلفه HostApduService
ممکن است روی یک دستگاه نصب شود و همان AID می تواند توسط بیش از یک سرویس ثبت شود. Android با استفاده از مراحل زیر تعیین می کند که کدام سرویس را فراخوانی کند:
- اگر برنامه کیف پول پیش فرض انتخاب شده کاربر AID را ثبت کرده باشد، آن برنامه فراخوانی می شود.
- اگر برنامه کیف پول پیشفرض AID را ثبت نکرده باشد، سرویسی که AID را ثبت کرده است فراخوانی میشود.
- اگر بیش از یک سرویس AID را ثبت کرده باشد، اندروید از کاربر میپرسد که کدام سرویس را فراخوانی کند.
بررسی کنید که آیا برنامه شما برنامه کیف پول پیش فرض است یا خیر
برنامهها میتوانند با ارسال RoleManager.ROLE_WALLET
به RoleManager.isRoleHeld()
بررسی کنند که آیا برنامه کیف پول پیشفرض هستند یا خیر.
اگر برنامه شما پیشفرض نیست، میتوانید نقش پیشفرض کیف پول را با ارسال RoleManager.ROLE_WALLET
به RoleManager.createRequestRoleIntent()
درخواست کنید.
برنامه های کیف پول
اندروید سرویسهای HCE را که یک گروه AID با دسته پرداخت را اعلام کردهاند به عنوان اپلیکیشن کیف پول در نظر میگیرد. اندروید 15 و بالاتر شامل یک نقش برنامه پیشفرض کیف پول است که کاربر میتواند با رفتن به تنظیمات > برنامهها > برنامههای پیشفرض آن را انتخاب کند. این برنامه کیف پول پیشفرض را برای فراخوانی هنگام ضربه زدن به پایانه پرداخت تعریف میکند.
دارایی های مورد نیاز برای برنامه های کیف پول
برای ارائه یک تجربه کاربری جذاب تر از نظر بصری، برنامه های کیف پول HCE باید یک بنر خدمات ارائه دهند.
اندروید 13 و بالاتر
برای تناسب بهتر با لیست انتخاب پرداخت پیشفرض در رابط کاربری تنظیمات، بنر مورد نیاز را روی یک نماد مربع تنظیم کنید. در حالت ایدهآل، باید با طراحی نماد راهانداز برنامه یکسان باشد. این تنظیم ثبات بیشتر و ظاهر تمیزتری ایجاد می کند.
اندروید 12 و پایین تر
اندازه بنر سرویس را روی 260x96 dp تنظیم کنید، سپس با افزودن ویژگی android:apduServiceBanner
به تگ <host-apdu-service>
، که به منبع قابل ترسیم اشاره می کند، اندازه بنر سرویس را در فایل 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>
حالت را مشاهده کنید
اندروید 15 ویژگی Observe Mode را معرفی می کند. وقتی فعال باشد، Observe Mode به دستگاه اجازه میدهد تا حلقههای نظرسنجی NFC را مشاهده کند و اعلانهای مربوط به آنها را به اجزای HostApduService
مناسب ارسال کند تا بتوانند برای تعامل با یک ترمینال NFC خاص آماده شوند. یک HostApduService
میتواند با ارسال true
به setObserveModeEnabled()
دستگاه را در حالت مشاهده قرار دهد. این به پشته NFC دستور می دهد تا تراکنش های NFC را مجاز نکند و در عوض به طور غیر فعال حلقه های نظرسنجی را مشاهده کند.
فیلترهای حلقه نظرسنجی
با استفاده از یکی از روش های زیر می توانید فیلترهای حلقه نظرسنجی را برای HostApduService
ثبت کنید:
-
registerPollingLoopFilterForService()
برای فیلترهایی که باید دقیقاً با چارچوب نظرسنجی مطابقت داشته باشند. -
registerPollingLoopPatternFilterForService()
برای فیلترهایی که با یک عبارت معمولی در برابر فریم های نظرسنجی مطابقت دارند.
هنگامی که یک فیلتر حلقه نظرسنجی با فریم های نظرسنجی غیر استاندارد مطابقت دارد، پشته NFC با فراخوانی متد processPollingFrames()
آن فریم های نظرسنجی را به HostApduService
مربوطه هدایت می کند. این به سرویس اجازه می دهد تا هر گونه اقدام لازم را برای اطمینان از آمادگی کاربر برای انجام تراکنش انجام دهد و قصد انجام این کار را دارد - به عنوان مثال، احراز هویت کاربر. اگر یک خواننده NFC فقط از فریمهای استاندارد در حلقه نظرسنجی خود استفاده میکند، پشته NFC آن فریمهای نظرسنجی را به سرویس پیشزمینه ترجیحی هدایت میکند، اگر آن سرویس در پیشزمینه باشد یا در غیر این صورت به نگهدارنده نقش کیف پول پیشفرض.
اعلانهای قاب نظرسنجی همچنین شامل اندازهگیری قدرت میدان مخصوص فروشنده است که میتوانید با فراخوانی getVendorSpecificGain()
را بازیابی کنید. فروشندگان میتوانند اندازهگیریها را با استفاده از مقیاس خودشان تا زمانی که در یک بایت باشد، ارائه دهند.
به حلقه های نظرسنجی پاسخ دهید و از حالت مشاهده خارج شوید
هنگامی که سرویس آماده تراکنش است، می تواند با ارسال false
به setObserveModeEnabled()
از Observe Mode خارج شود. سپس پشته NFC اجازه می دهد تا تراکنش ها ادامه یابد.
مؤلفههای HostApduService
میتوانند هر زمان که سرویس پرداخت ترجیحی هستند، با تنظیم shouldDefaultToObserveMode
روی true
در مانیفست یا با فراخوانی CardEmulation.setShouldDefaultToObserveModeForService()
نشان دهند که Observe Mode باید فعال شود.
مؤلفههای HostApduService
و OffHostApduService
همچنین میتوانند نشان دهند که فیلترهای حلقه نظرسنجی که با فریمهای حلقه نظرسنجی دریافتی مطابقت دارند، باید بهطور خودکار حالت مشاهده را غیرفعال کنند و با تنظیم autoTransact
روی true
در اعلان PollingLoopFilter
در مانیفست، اجازه دهند تراکنشها ادامه یابد.
صفحه نمایش خاموش و رفتار قفل صفحه
رفتار سرویسهای HCE بر اساس نسخه اندرویدی که روی دستگاه اجرا میشود، متفاوت است.
اندروید 12 و بالاتر
در برنامههایی که Android 12 (سطح API 31) و بالاتر را هدف قرار میدهند، میتوانید پرداختهای NFC را بدون روشن بودن صفحهنمایش دستگاه با تنظیم requireDeviceScreenOn
روی false
فعال کنید.
اندروید 10 و بالاتر
دستگاههای دارای Android 10 (سطح API 29) یا بالاتر از NFC امن پشتیبانی میکنند. هنگامی که Secure NFC روشن است، همه شبیهسازهای کارت (برنامههای میزبان و برنامههای خارج از میزبان) وقتی صفحه دستگاه خاموش است، در دسترس نیستند. هنگامی که Secure NFC خاموش است، برنامه های خارج از میزبان زمانی که صفحه دستگاه خاموش است در دسترس هستند. با استفاده از isSecureNfcSupported()
می توانید پشتیبانی از NFC امن را بررسی کنید.
در دستگاههایی که Android 10 و بالاتر دارند، همان عملکرد برای تنظیم android:requireDeviceUnlock
روی true
اعمال میشود که برای دستگاههای دارای Android 9 و پایینتر اعمال میشود، اما فقط زمانی که Secure NFC خاموش باشد. یعنی اگر Secure NFC روشن باشد، سرویسهای HCE بدون در نظر گرفتن تنظیمات android:requireDeviceUnlock
نمیتوانند از صفحه قفل کار کنند.
اندروید 9 و پایین تر
در دستگاههایی که اندروید 9 (سطح API 28) و پایینتر دارند، کنترلکننده NFC و پردازنده برنامه با خاموش شدن صفحه نمایش دستگاه بهطور کامل خاموش میشوند. بنابراین خدمات HCE وقتی صفحه نمایش خاموش است کار نمی کنند.
همچنین در اندروید 9 و پایینتر، سرویسهای HCE میتوانند از صفحه قفل کار کنند. با این حال، این توسط ویژگی android:requireDeviceUnlock
در تگ <host-apdu-service>
سرویس HCE شما کنترل می شود. به طور پیشفرض، باز کردن قفل دستگاه مورد نیاز نیست، و حتی اگر دستگاه قفل باشد، سرویس شما فراخوانی میشود.
اگر ویژگی android:requireDeviceUnlock
برای سرویس HCE خود روی true
تنظیم کنید، Android از کاربر میخواهد قفل دستگاه را در صورت بروز موارد زیر باز کند:
- کاربر به یک خواننده NFC ضربه می زند.
- خواننده NFC یک AID را انتخاب می کند که برای سرویس شما حل شده است.
پس از باز کردن قفل، اندروید یک گفتگو را نشان می دهد که از کاربر می خواهد برای تکمیل تراکنش دوباره ضربه بزند. این امر ضروری است زیرا ممکن است کاربر دستگاه را از NFC خوان دور کرده باشد تا قفل آن را باز کند.
همزیستی با کارت های عنصر امن
این بخش برای توسعهدهندگانی که برنامهای را اجرا کردهاند که به یک عنصر امن برای شبیهسازی کارت متکی است، جالب است. پیاده سازی HCE اندروید به گونه ای طراحی شده است که به موازات سایر روش های پیاده سازی شبیه سازی کارت، از جمله استفاده از عناصر امن، کار کند.
این همزیستی بر اساس اصلی به نام مسیریابی AID است. کنترلر NFC یک جدول مسیریابی را نگه می دارد که شامل یک لیست (متناهی) از قوانین مسیریابی است. هر قانون مسیریابی شامل یک AID و یک مقصد است. مقصد میتواند CPU میزبان، جایی که برنامههای Android در حال اجراست، یا یک عنصر امن متصل باشد.
هنگامی که خواننده NFC یک APDU را با یک SELECT AID
ارسال می کند، کنترل کننده NFC آن را تجزیه می کند و بررسی می کند که آیا AID ها با هر AID در جدول مسیریابی آن مطابقت دارند یا خیر. اگر مطابقت داشته باشد، آن APDU و همه APDU های زیر آن به مقصد مرتبط با AID ارسال می شوند تا زمانی که SELECT AID
APDU دیگری دریافت شود یا پیوند NFC خراب شود.
شکل 4 این معماری را نشان می دهد:
کنترلر NFC معمولاً دارای یک مسیر پیش فرض برای APDU ها نیز می باشد. هنگامی که یک AID در جدول مسیریابی یافت نمی شود، از مسیر پیش فرض استفاده می شود. در حالی که این تنظیم ممکن است از دستگاهی به دستگاه دیگر متفاوت باشد، دستگاههای Android باید مطمئن شوند که ایدزهای ثبتشده توسط برنامه شما به درستی به میزبان هدایت میشوند.
برنامههای اندرویدی که سرویس HCE را پیادهسازی میکنند یا از یک عنصر امن استفاده میکنند، لازم نیست نگران پیکربندی جدول مسیریابی باشند. که توسط اندروید به صورت خودکار مدیریت می شود. اندروید فقط باید بداند که کدام ایدز را میتوان توسط سرویسهای HCE مدیریت کرد و کدامها را میتوان توسط عنصر امن کنترل کرد. جدول مسیریابی به طور خودکار بر اساس سرویس هایی که نصب شده اند و کاربر به عنوان ترجیحی پیکربندی کرده است، پیکربندی می شود.
بخش زیر نحوه اعلان 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>
نمونه زیر نمونه ای از فایل apduservice.xml
مربوطه است که دو 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>
ویژگی android:requireDeviceUnlock
برای سرویسهای خارج از میزبان اعمال نمیشود، زیرا CPU میزبان در تراکنش دخالت ندارد و بنابراین نمیتواند از اجرای تراکنشهای عنصر امن در زمانی که دستگاه قفل است جلوگیری کند.
ویژگی android:apduServiceBanner
برای سرویسهای خارج از میزبانی که برنامههای پرداخت هستند و به عنوان یک برنامه پرداخت پیشفرض قابل انتخاب هستند، لازم است.
فراخوان خدمات خارج از میزبان
Android هرگز سرویسی را که به عنوان "خارج از میزبان" اعلام شده است راه اندازی نمی کند یا به آن متصل نمی شود، زیرا تراکنش های واقعی توسط عنصر امن و نه توسط سرویس Android انجام می شود. اعلامیه خدمات صرفاً به برنامه های کاربردی اجازه می دهد تا ایدزهای موجود در عنصر امن را ثبت کنند.
HCE و امنیت
معماری HCE یک بخش اصلی امنیت را فراهم می کند: از آنجا که سرویس شما توسط مجوز سیستم BIND_NFC_SERVICE
محافظت می شود، فقط سیستم عامل می تواند به سرویس شما متصل شود و با آن ارتباط برقرار کند. این تضمین می کند که هر APDU که دریافت می کنید در واقع یک APDU است که توسط سیستم عامل از کنترلر NFC دریافت شده است، و هر APDU که ارسال می کنید فقط به سیستم عامل می رود که به نوبه خود مستقیماً APDU ها را به کنترل کننده NFC ارسال می کند.
آخرین نگرانی باقی مانده این است که داده های خود را از کجا دریافت می کنید که برنامه شما به خواننده NFC ارسال می کند. این به طور عمدی در طراحی HCE جدا شده است. اهمیتی نمیدهد که دادهها از کجا میآیند، فقط مطمئن میشوند که به طور ایمن به کنترلکننده NFC و به خواننده NFC منتقل میشوند.
برای ذخیره و بازیابی ایمن دادههایی که میخواهید از سرویس HCE خود ارسال کنید، میتوانید به عنوان مثال به Android Application Sandbox تکیه کنید که دادههای برنامه شما را از برنامههای دیگر جدا میکند. برای جزئیات بیشتر درباره امنیت 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 تعامل داشته باشند باید صریحاً فقط بیت ششم را بررسی کنند و SEL_RES
کامل را با مقدار 0x20 مقایسه نکنند .
فعال سازی ISO-DEP
پس از فعال شدن پروتکل Nfc-A، خواننده NFC فعال سازی پروتکل ISO-DEP را آغاز می کند. این دستور RATS (درخواست پاسخ به انتخاب) را ارسال می کند. کنترل کننده NFC پاسخ RATS را تولید می کند. ATS توسط خدمات HCE قابل تنظیم نیست. با این حال، اجرای HCE باید الزامات انجمن NFC را برای پاسخ ATS برآورده کند، بنابراین خوانندگان NFC می توانند روی این پارامترها حساب کنند که مطابق با الزامات انجمن NFC برای هر دستگاه HCE تنظیم شده است.
بخش زیر جزئیات بیشتری را در مورد تک بایت های پاسخ ATS ارائه شده توسط کنترل کننده NFC در دستگاه HCE ارائه می دهد:
- TL: طول پاسخ ATS. نباید طولی بیشتر از 20 بایت را نشان دهد.
- T0: بیت های 5، 6 و 7 باید در تمام دستگاه های HCE تنظیم شوند، که نشان می دهد TA(1)، TB(1) و TC(1) در پاسخ ATS گنجانده شده اند. بیت های 1 تا 4 FSCI را نشان می دهند و حداکثر اندازه فریم را کدگذاری می کنند. در دستگاه های HCE مقدار FSCI باید بین 0h و 8h باشد.
- 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 را روی صفر تنظیم کنند.
- بایت های تاریخی: دستگاه های HCE ممکن است تا 15 بایت تاریخی را برگردانند. خوانندگان NFC که مایل به تعامل با سرویس های HCE هستند نباید هیچ فرضی در مورد محتوای بایت های تاریخی یا حضور آنها داشته باشند.
توجه داشته باشید که بسیاری از دستگاههای HCE احتمالاً مطابق با الزامات پروتکلی هستند که شبکههای پرداخت متحد در EMVCo در مشخصات «پروتکل ارتباطات بدون تماس» خود مشخص کردهاند. به طور خاص:
- FSCI در T0 باید بین 2h و 8h باشد.
- T(A)1 باید روی 0x80 تنظیم شود، که نشان می دهد فقط نرخ بیت 106 کیلوبیت بر ثانیه پشتیبانی می شود و نرخ بیت نامتقارن بین خواننده و شبیه ساز پشتیبانی نمی شود.
- FWI در T(B)1 باید <= 7 ساعت باشد.
تبادل داده APDU
همانطور که قبلا ذکر شد، پیاده سازی HCE تنها از یک کانال منطقی پشتیبانی می کند. تلاش برای انتخاب برنامهها در کانالهای منطقی مختلف در دستگاه HCE کار نمیکند.