סקירה כללית על אמולציית כרטיסים מבוססת-מארח

הרבה מכשירים מבוססי Android שמציעים פונקציונליות NFC כבר תומכים ב-NFC האמולציה של כרטיסים. ברוב המקרים, האמולציה של הכרטיס מתבצעת על ידי צ'יפ נפרד מהמכשיר, שנקרא רכיב מאובטח. כרטיסי SIM רבים מסופקים על ידי ספקים אלחוטיים מכילים גם רכיב מאובטח.

Android מגרסה 4.4 ואילך מספק שיטה נוספת להדמיית כרטיס לא כוללת רכיב מאובטח, שנקרא אמולציית כרטיסים מבוססת-מארח. הזה מאפשר לכל אפליקציה ב-Android לחקות כרטיס ולדבר ישירות עם NFC בקורא. בנושא הזה מוסבר איך פועלת אמולציית כרטיסים מבוססת-מארח (HCE) ב-Android ואיך אפשר לפתח אפליקציה שמחקה כרטיס NFC באמצעות לעיבוד טקסט.

אמולציית כרטיסים עם רכיב מאובטח

אם אמולציית כרטיס NFC מסופקת באמצעות רכיב מאובטח, הכרטיס האמולציה מוקצה לרכיב המאובטח במכשיר באמצעות מכשיר Android תרגום מכונה. לאחר מכן, כשהמשתמש מחזיק את המכשיר מעל מסוף NFC, לחצן ה-NFC בקר במכשיר מנתב את כל הנתונים מהקורא ישירות אל לרכיב מסוים. איור 1 ממחיש את הרעיון הזה:

תרשים עם קורא NFC שעובר דרך בקר NFC כדי לאחזר מידע מרכיב מאובטח
איור 1. אמולציית כרטיס NFC עם רכיב מאובטח.

הרכיב המאובטח עצמו מבצע את התקשורת עם מסוף ה-NFC, אף אפליקציית Android לא מעורבת בעסקה. אחרי שהעסקה ישלים אפליקציה ל-Android כדי לשלוח שאילתה על הרכיב המאובטח ישירות סטטוס העסקה וליידע את המשתמש.

אמולציית כרטיסים מבוססת-מארח

כשמתבצעת אמולציה של כרטיס NFC באמצעות אמולציית כרטיסים מבוססת-מארח, הנתונים מנותבים ישירות למעבד של המארח במקום לנתב לרכיב מאובטח. איור 2 ממחישה איך פועלת אמולציית כרטיסים מבוססת-מארח:

תרשים עם קורא NFC שעובר דרך בקר NFC כדי לאחזר מידע מהמעבד (CPU)
איור 2. אמולציית כרטיס NFC ללא רכיב מאובטח.

כרטיסים ופרוטוקולים נתמכים של NFC

תרשים שמציג סטאק פרוטוקול HCE
איור 3. סטאק פרוטוקול HCE של Android.

תקני NFC מציעים תמיכה בפרוטוקולים רבים ושונים, סוגים שונים של כרטיסים שאפשר לחקות.

מערכת Android 4.4 ואילך תומכת במספר פרוטוקולים שנפוצים בשוק היום. הרבה כרטיסים קיימים ללא מגע כבר מבוססים על הפרוטוקולים האלה, כמו כרטיסי תשלום 'מצמידים ומשלמים'. הפרוטוקולים האלה נתמכים גם על ידי הרבה קוראי NFC בשוק כיום, כולל מכשירי Android NFC שפועלים כמו הקוראים עצמם (מידע נוסף זמין בIsoDep הכיתה). כך תוכלו לפתח ולפרוס פתרון NFC מקצה לקצה HCE באמצעות מכשירים מבוססי Android בלבד.

באופן ספציפי, מערכת Android 4.4 ואילך תומכת בהדמיית כרטיסים שמבוססים על מפרט ISO-DEP של NFC-Forum (מבוסס על ISO/IEC 14443-4) והעיבוד יחידות נתונים של פרוטוקולי אפליקציה (APDU) כפי שמוגדרות ב-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 ב-Android מבוססת על Android Service רכיבים (שנקראים HCE שירותים). אחד היתרונות המרכזיים של שירות הוא שהוא יכול לפעול ברקע ללא ממשק משתמש. זו התאמה טבעית להרבה מכשירי HCE לאפליקציות, כמו כרטיסי מועדון לקוחות או כרטיסי תחבורה ציבורית, שהמשתמש לא צריך יותר. להפעיל אפליקציה כדי להשתמש בה. במקום זאת, הקשה על המכשיר מול קורא ה-NFC מופעלת השירות הנכון, אם הוא עדיין לא פועל ומבצע את העסקה ברקע. כמובן, אתה מוזמן להפעיל ממשק משתמש נוסף (כמו הודעות משתמש) מהשירות שלך כאשר יש צורך.

בחירת שירות

כשהמשתמש מקיש על מכשיר לקורא NFC, מערכת Android צריכה לדעת על כך שירות HCE שקורא ה-NFC רוצה לתקשר איתו. תקן ISO/IEC 7816-4 המפרט מגדיר דרך לבחירת אפליקציות, המתמקדת סביב מזהה האפליקציה (AID). AID מורכב מ-16 בייטים לכל היותר. אם מבצעים אמולציה כרטיסים לתשתית קיימת של קורא NFC, מזהי ה-AID שהקוראים האלה בדרך כלל ידועים וגלויים לכולם (לדוגמה, מזהי AID של רשתות תשלומים כמו Visa ו-MasterCard).

אם אתם רוצים לפרוס תשתית קוראים חדשה לאפליקציה שלכם, לרשום את מזהי ה-AID שלכם. הליך הרישום של מזהי AID מוגדר כאן: מפרט ISO/IEC 7816-5. מומלץ לרשום מספר AID בהתאם לתקן 7816-5 אם אתם פורסים אפליקציית HCE ל-Android, כי היא מונעת התנגשויות עם אפליקציות אחרות.

קבוצות AID

במקרים מסוימים, יכול להיות ששירות HCE יצטרך לרשום כמה מזהי AID ולהגדיר ה-handler שמוגדר כברירת מחדל לכל מזהי ה-AID כדי להטמיע תרגום מכונה. אי אפשר להשתמש בחלק ממזהי AID בקבוצה שמפנים לשירות אחר.

הרשימה של מזהי AID שנשמרים יחד נקראת קבוצת AID. עבור כל מספרי ה-AID ב- קבוצת AID, Android מבטיחה אחת מהאפשרויות הבאות:

  • כל מזהי ה-AID בקבוצה מנותבים לשירות HCE הזה.
  • בקבוצה לא ינותבו מכשירי AID לשירות ה-HCE הזה (לדוגמה, כי המשתמש העדיף שירות אחר שביקש מספר AID אחד או יותר בקבוצה שלך גם כן).

כלומר, אין מצב ביניים, שבו חלק ממזהי ה-AID בקבוצה יכולים להיות ינותב לשירות HCE אחד וחלק לשירות אחר.

קבוצות וקטגוריות של AID

אפשר לשייך כל קבוצת AID לקטגוריה. כך תהיה ל-Android אפשרות לקבץ שירותי HCE יחד לפי קטגוריה, וכך המשתמש יכול להגדיר כברירת מחדל ברמת הקטגוריה ולא ברמת AID. אין לציין מזהי AID בחלקים הגלויים למשתמשים של האפליקציה, כי אין להם משמעות למשתמש הממוצע.

מערכת Android 4.4 ואילך תומכת בשתי קטגוריות:

  • CATEGORY_PAYMENT (כולל אפליקציות תשלומים שמקובלות בתחום)
  • CATEGORY_OTHER (עבור כל שאר אפליקציות HCE)

הטמעת שירות HCE

כדי לאמולציה של כרטיס NFC באמצעות אמולציית כרטיסים מבוססת-מארח, צריך ליצור רכיב Service שמטפל בעסקאות NFC.

בדיקה אם יש תמיכה ב-HCE

האפליקציה שלך יכולה לבדוק אם המכשיר תומך ב-HCE על ידי בדיקת FEATURE_NFC_HOST_CARD_EMULATION . שימוש ב<uses-feature> במניפסט של האפליקציה כדי להצהיר שהאפליקציה משתמשת ב-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 מוצהר על שתי שיטות מופשטות שצריך לבטל ו להטמיע. אחת מהאפשרויות האלה, processCommandApdu() נשלחת קריאה בכל פעם שקורא NFC שולח יחידת נתונים של פרוטוקול אפליקציה (APDU) לשירות שלך. מזהי APDU מוגדרים במפרט ISO/IEC 7816-4. יחידות APDU הן החבילות ברמת האפליקציה שמועברות בין קורא ה-NFC לבין שירות HCE שלך. הפרוטוקול ברמת האפליקציה הוא חצי דו-צדדי: קורא NFC שולח פקודת APDU, והוא ממתין לשליחת תגובה APDU החזרה.

כפי שצוין קודם, Android משתמש ב-AID כדי לקבוע איזה שירות HCE שקורא רוצה לדבר איתו. בדרך כלל, ה-APDU הראשון שקורא NFC שולח המכשיר הוא APDU של SELECT AID. ה-APDU הזה מכיל את ה-AID שהקורא רוצה לדבר איתם. מערכת Android מחלצת את קובץ ה-AID מ-APDU והופכת אותו ל-HCE ולאחר מכן מעביר את ה-APDU הזה לשירות שטופל.

אפשר לשלוח תשובה מ-APDU על ידי החזרת הבייטים של ה-APDU של התשובה מ- processCommandApdu() חשוב לזכור שהשיטה הזו נקראת בשרשור הראשי של האפליקציה שלך, שאסור לחסום. אם אין לכם אפשרות לחשב ולהחזיר את הנתונים תגובה APDU באופן מיידי, החזרת null. לאחר מכן תוכלו לבצע את העבודה הדרושה שרשור אחר ולהשתמש sendResponseApdu() מוגדרת במחלקה HostApduService לשליחת התשובה כאשר בוצע.

מערכת Android ממשיכה להעביר מפתחות APDU חדשים מהקורא אל השירות שלך, עד יקרה אחד מהמצבים הבאים:

  • קורא ה-NFC שולח עוד APDU של SELECT AID, ומערכת ההפעלה מקודדת שירות שונה.
  • קישור ה-NFC בין קורא ה-NFC לבין המכשיר לא תקין.

בשני המקרים האלה, הכיתה onDeactivated() מתבצעת קריאה עם ארגומנט שמציין איזה מבין השניים קרה.

אם אתם עובדים עם תשתית קוראים קיימת, עליכם להטמיע את פרוטוקול קיים ברמת האפליקציה שהקוראים מצפים לו בשירות ה-HCE.

אם פורסים תשתית קוראים חדשה שנמצאת גם בשליטה שלך, יכולים להגדיר פרוטוקול ורצף APDU משלכם. כדאי לנסות להגביל את כמות ה-APDU ואת גודל הנתונים להחליף: כך תוודא שהמשתמשים שלך כדי להצמיד את המכשיר לקורא ה-NFC לזמן קצר. א' גבול עליון סביר הוא כ-1KB של נתונים. בדרך כלל הוחלפו תוך 300 אלפיות שנייה.

הצהרה על מניפסט השירות ורישום AID

עליך להצהיר על השירות שלך במניפסט כרגיל, אבל חובה להוסיף חלק חלקים נוספים להצהרת השירות:

  1. כדי לומר לפלטפורמה שמדובר בשירות HCE שמטמיע הממשק HostApduService, צריך להוסיף מסנן Intent עבור SERVICE_INTERFACE פעולה להצהרת השירות שלך.

  2. כדי לציין לפלטפורמה אילו קבוצות AID השירות הזה מבקש, צריך לכלול A 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 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> חייב להכיל מאפיין <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 בפורמט הקסדצימלי ולוודא שהוא מכיל גרף מספר התווים.

בנוסף, האפליקציה צריכה להחזיק הרשאה ל-NFC להירשם בתור שירות HCE.

פתרון התנגשויות AID

אפשר להתקין מספר רכיבים של HostApduService במכשיר אחד, וגם אפשר לרשום את אותו AID ביותר משירות אחד. מערכת Android מאתרת AID יש הבדלים שונים בהתאם לקטגוריה שאליה שייכת AID. כל אחד ייתכן שלקטגוריה יש מדיניות שונה לפתרון מחלוקות.

בקטגוריות מסוימות, כגון תשלומים, ייתכן שהמשתמש יוכל לבחור ברירת מחדל שירות בממשק המשתמש של ההגדרות של Android. בקטגוריות אחרות, המדיניות יכולה להיות לשאול את המשתמש תמיד איזה שירות להפעיל במקרה של התנגשות. למידע לגבי האופן שבו ניתן לשלוח שאילתות לגבי המדיניות בנושא יישוב סכסוכים לגבי קטגוריה מסוימת, ראה getSelectionModeForCategory()

בודקים אם השירות מוגדר כברירת המחדל

האפליקציות יכולות לבדוק אם שירות HCE שלהן הוא שירות ברירת המחדל קטגוריה מסוימת באמצעות isDefaultServiceForCategory() API.

אם השירות שלך לא מוגדר כברירת המחדל, אפשר לבקש שהוא יוגדר כברירת המחדל. באמצעות ACTION_CHANGE_DEFAULT

בקשות תשלום

מערכת Android מתייחסת לשירותי HCE שהכריזו על קבוצת AID עם payment בתור אפליקציות תשלום. Android 4.4 ואילך מכיל ערך בתפריט הגדרות ברמה העליונה שנקרא מקישים & pay, שסופר את כל יישומים תשלומים כאלה. בתפריט ההגדרות הזה, המשתמש יכול לבחור את אפליקציית התשלום שמוגדרת כברירת מחדל, שמופעלת כשמקישים על מסוף התשלום.

נכסים נדרשים לאפליקציות של תשלומים

כדי לספק חוויית משתמש אטרקטיבית יותר, אפליקציות התשלום של HCE נדרשים לספק באנר שירות.

Android מגרסה 13 ואילך

כדי שתהיה התאמה טובה יותר לרשימת ברירת המחדל של אמצעי התשלום בממשק המשתמש של ההגדרות, צריך לשנות את דרישה של מודעת באנר לסמל של ריבוע. באופן אידיאלי, הוא צריך להיות זהה עיצוב הסמל של מרכז האפליקציות. ההתאמה הזו יוצרת יותר עקביות למראה נקי יותר.

Android מגרסה 12 ומטה

מגדירים את הגודל של באנר השירות ל-260x96dp ולאחר מכן מגדירים את הגודל של באנר השירות. בקובץ ה-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>

ההתנהגות של כיבוי המסך ושל מסך הנעילה

ההתנהגות של שירותי 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 רק צריכה לדעת באילו מזהי AID אפשר לטפל באמצעות שירותי HCE ובאילו שירותים הרכיב המאובטח יכול לטפל. הניתוב מוגדרת באופן אוטומטי על סמך השירותים שהותקנו, שהמשתמש הגדיר כמועדפת.

בקטע הבא מוסבר איך להצהיר על מזהי AID באפליקציות שמשתמשות ב-AID רכיב מאובטח לאמולציית כרטיסים.

רישום AID של רכיב מאובטח

אפליקציות שמשתמשות ברכיב מאובטח להדמיית כרטיס יכולות להצהיר off-host במניפסט. ההצהרה על שירות כזה כמעט זהה להצהרה של שירות 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:

<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 Apps Sandbox, למשל היא מבודדת את נתוני האפליקציה שלכם מאפליקציות אחרות. לפרטים נוספים על Android אבטחה, כדאי לקרוא את המאמר טיפים בנושא אבטחה.

פרמטרים ופרטים של הפרוטוקול

הקטע הזה רלוונטי למפתחים שרוצים להבין איזה פרוטוקול הפרמטרים שמכשירי HCE משתמשים בהם במהלך שלבי ההגנה מפני התנגשות והפעלה של הפרוטוקולים של NFC. כך אפשר לבנות תשתית של קוראים תואם למכשירי Android HCE.

הגנה מפני התנגשות והפעלה באמצעות פרוטוקול Nfc-A (ISO/IEC 14443 type A)

במסגרת ההפעלה של פרוטוקול Nfc-A, מתבצעת החלפה של מספר פריימים.

בחלק הראשון של ההחלפה, מכשיר ה-HCE מציג את ה-UID שלו. מכשירי HCE צריך להניח שיש לו UID אקראי. כלומר, בכל הקשה ה-UID שמוצג לקורא הוא UID שנוצר באופן אקראי. לכן, קוראי NFC לא צריכים להסתמך על ה-UID של מכשירי HCE בתור באימות או בזיהוי.

קורא ה-NFC יכול בהמשך לבחור את מכשיר ה-HCE על ידי שליחת SEL_REQ הפקודה. התגובה SEL_RES של מכשיר ה-HCE כוללת לפחות את הביט השישי מוגדרת (0x20), שמציינת שהמכשיר תומך ב-ISO-DEP. שימו לב שקטעים אחרים ב- SEL_RES יכול להיות מוגדר גם כן, מה שמציין למשל תמיכה ב-NFC-DEP (p2p). מכיוון שקטעים אחרים עשויים להיות מוגדרים, קוראים שירצו לקיים אינטראקציה מכשירי HCE צריכים לבדוק באופן מפורש את הביט השישי בלבד, ולא להשוות ביניהם SEL_RES המלא עם ערך של 0x20.

הפעלה של ISO-DEP

לאחר ההפעלה של פרוטוקול Nfc-A, קורא ה-NFC מפעיל את ISO-DEP הפעלת פרוטוקול. הוא שולח RATS (Request for Answer to Select) הפקודה. בקר ה-NFC יוצר את תגובת RATS, ATS; ה-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 חייב להיות בין 0:00 ל-8:00.
  • T(A)1: מגדיר את קצבי העברת הנתונים בין הקורא לאמולטור והאם הם יכולים אסימטרית. אין דרישות או אחריות לגבי קצב העברת נתונים למכשירי HCE.
  • T(B)1: ביטים 1 עד 4 מציינים את מספר הימים של מגן הזמן של Start-up Frame (SFGI). במצב מופעל מכשירי HCE, SFGI חייב להיות פחות מ-8 שעות. סיביות 5 עד 8 מציינות שהמסגרת בהמתנה מספר שלם של זמן (FWI) ומקודד לפי זמן ההמתנה למסגרת (FWT). במכשירי HCE, FWI חייב להיות פחות מ-8 שעות.
  • T(C)1: ביט 5 מציין תמיכה ב'תכונות פרוטוקול מתקדמות'. מכשירי HCE עשוי לתמוך ב'תכונות פרוטוקול מתקדמות', וייתכן שלא. Bit 2 מציין שיש תמיכה ל-DID. מכשירי HCE עשויים לתמוך ב-DID, אבל לא בהכרח. Bit 1 מצביע על תמיכה ב- NAD. מכשירי HCE לא יכולים לתמוך ב-NAD וצריך להגדיר את הביט 1 לאפס.
  • בייטים היסטוריים: מכשירי HCE יכולים להחזיר עד 15 בייטים היסטוריים. NFC קוראים שמוכנים ליצור אינטראקציה עם שירותי HCE לא צריכים להניח הנחות לגבי את תוכן הבייטים ההיסטוריים או הנוכחות שלהם.

חשוב לזכור שמכשירי HCE רבים כנראה עומדים בדרישות הפרוטוקולים שרשתות התשלומים המאוחדות ב-EMVCo ציינו Communication Protocol" למפרט. ובפרט:

  • זמן ה-FSCI ב-T0 צריך להיות בין שעתיים ל-8 שעות.
  • הערך T(A)1 צריך להיות מוגדר ל-0x80, שמציין שרק קצב העברת הנתונים של 106kbit/s וקצבי העברת נתונים אסימטריים בין הקורא לאמולטור אינם נתמך.
  • FWI ב-T(B)1 חייב להיות <= 7 שעות.

חילופי נתונים של APDU

כפי שצוין קודם, הטמעות של HCE תומכות רק בערוץ לוגי אחד. הניסיונות לבחור אפליקציות בערוצים לוגיים שונים לא יצליחו מכשיר HCE.