מזהי המכשיר

ב-Android 10 השתנו ההרשאות למזהי המכשיר, כך שכל מזהי המכשיר מוגנים עכשיו באמצעות ההרשאה READ_PRIVILEGED_PHONE_STATE. לפני Android 10, מזהי מכשירים קבועים (IMEI/MEID,‏ IMSI,‏ SIM והמספר הסידורי של ה-Build) היו מוגנים באמצעות ההרשאה בסביבת זמן הריצה READ_PHONE_STATE. ההרשאה READ_PRIVILEGED_PHONE_STATE ניתנת רק לאפליקציות שחתומות על ידי מפתח הפלטפורמה ולאפליקציות מערכת בעלות הרשאות.

מידע נוסף על דרישות ההרשאות החדשות זמין בדפי ה-Javadoc של TelephonyManager.java ושל Build.java.

השינוי הזה משפיע על ממשקי ה-API הבאים:

  • TelephonyManager#getDeviceId
  • TelephonyManager#getImei
  • TelephonyManager#getMeid
  • TelephonyManager#getSimSerialNumber
  • TelephonyManager#getSubscriberId
  • Build#getSerial

גישה לאפליקציות של ספקי סלולר ללא ההרשאה READ_PRIVILEGED_PHONE_STATE

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

אפשרות תיאור מגבלות
הרשאות של ספק UICC פלטפורמת Android טוענת אישורים שמאוחסנים ב-UICC ומעניקה הרשאה לאפליקציות שחתמו עליהם אישורים אלה לבצע קריאות לשיטות מיוחדות. למפעילים מהדור קודם יש אוכלוסייה גדולה של כרטיסי SIM מבוססים, שקשה מאוד לעדכן. בנוסף, ספקים שאין להם הרשאות כתיבת כרטיסי SIM חדשים (לדוגמה, ספקי MVNO שיש להם כרטיסי SIM שהנפיקו ספקי MNO) לא יכולים להוסיף או לעדכן אישורים בכרטיסי ה-SIM.
הוספה לרשימת ההיתרים של OEM יצרני ציוד מקורי יכולים להשתמש ב-OP_READ_DEVICE_IDENTIFIER כדי לספק מזהי מכשירים לאפליקציות של ספקים שמופיעות ברשימת ההיתרים. הפתרון הזה לא מתאים לכל הספקים.
קוד הקצאת סוג (TAC) משתמשים בשיטה getTypeAllocationCode, שהוצגה ב-Android 10, כדי לחשוף את TAC שמחזיר את פרטי היצרן והדגם. המידע ב-TAC לא מספיק כדי לזהות מכשיר ספציפי.
מערך למספור מספרי הטלפון (MSISDN) ספקי הסלולר יכולים להשתמש במספר הטלפון (MSISDN) שזמין בקטע TelephonyManager עם קבוצת ההרשאות PHONE כדי לחפש את מספר ה-IMEI במערכות הקצה העורפי שלהם. כדי לעשות זאת, נדרש מהספקים השקעה משמעותית. ספקים שממפים את מפתחות הרשת שלהם באמצעות IMSI צריכים משאבים טכניים משמעותיים כדי לעבור ל-MSISDN.

כל האפליקציות של ספקי הסלולר יכולות לגשת למזהי המכשיר על ידי עדכון הקובץ CarrierConfig.xml בגיבוב של אישור החתימה של האפליקציה של ספק הסלולר. כשאפליקציית ספק הסלולר קוראת לשיטה לקריאת מידע בעל הרשאות, הפלטפורמה מחפשת התאמה של גיבוב אישור החתימה של האפליקציה (חתימת SHA-1 או SHA-256 של האישור) בקובץ CarrierConfig.xml. אם נמצאה התאמה, המידע המבוקש מוחזר. אם לא נמצאה התאמה, מוחזרת החרגת אבטחה.

כדי להטמיע את הפתרון הזה, הספקים חייבים לפעול לפי השלבים הבאים:

  1. מעדכנים את CarrierConfig.xml ב-hash של אישור החתימה של אפליקציית הספק ושולחים תיקון.
  2. מבקשים מהיצרנים לעדכן את ה-build שלהם עם QPR1 ואילך (מומלץ) או עם תיקוני הפלטפורמה הנדרשים ועם התיקון שמכיל את הקובץ CarrierConfig.xml המעודכן משלב 1 שלמעלה.

הטמעה

מעדכנים את רשימת ההיתרים להרשאות בעלות הרשאות כדי להעניק את ההרשאה READ_PRIVILEGED_PHONE_STATE לאפליקציות בעלות הרשאות שדורשות גישה למזהי המכשיר.

מידע נוסף על הוספה לרשימת ההיתרים זמין במאמר הוספה של הרשאות עם הרשאות גישה לרשימת ההיתרים.

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

  • אם האפליקציה היא אפליקציה בעלת הרשאות שהוטענה מראש, היא זקוקה להרשאה READ_PRIVILEGED_PHONE_STATE שמוצהרת בקובץ AndroidManifest.xml. האפליקציה צריכה גם להוסיף את ההרשאה הזו לרשימת ההיתרים.
  • אפליקציות שמוצגות דרך Google Play צריכות הרשאות של ספק. מידע נוסף על הענקת הרשאות לספקים זמין בדף UICC Carrier Privileges.
  • אפליקציה של בעל מכשיר או בעל פרופיל שקיבלה את ההרשאה READ_PHONE_STATE.

באפליקציה שלא עומדת באף אחת מהדרישות האלה, מתרחש ההתנהגות הבאה:

  • אם האפליקציה מטרגטת גרסאות קודמות ל-Q ולא הוענקה לה ההרשאה READ_PHONE_STATE, מתבצעת הפעלה של SecurityException. זוהי ההתנהגות הנוכחית בגרסאות קודמות ל-Q, כי ההרשאה הזו נדרשת כדי להפעיל את ממשקי ה-API האלה.
  • אם האפליקציה מטרגטת גרסאות לפני Q והיא קיבלה את ההרשאה READ_PHONE_STATE, היא מקבלת ערך null לכל ממשקי ה-API של TelephonyManager ו-Build.UNKNOWN לשיטה Build#getSerial.
  • אם האפליקציה מטרגטת ל-Android מגרסה 10 ואילך ולא עומדת באף אחת מהדרישות החדשות, היא תקבל הודעת SecurityException.

אימות ובדיקה

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

בדיקות ה-CTS הבאות ספציפיות לתכונה הזו.

cts-tradefed run cts -m CtsCarrierApiTestCases -t
    android.carrierapi.cts.CarrierApiTest

cts-tradefed run cts -m CtsTelephonyTestCases -t
    android.telephony.cts.TelephonyManagerTest

cts-tradefed run cts -m CtsTelephony3TestCases

cts-tradefed run cts -m CtsPermissionTestCases -t
    android.permission.cts.TelephonyManagerPermissionTest

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCanGetDeviceIdentifiers

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCanGetDeviceIdentifiers

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.ManagedProfileTest#testProfileOwnerCannotGetDeviceIdentifiersWithoutPermission

cts-tradefed run cts -m CtsDevicePolicyManagerTestCases -t
    com.android.cts.devicepolicy.DeviceOwnerTest#testDeviceOwnerCannotGetDeviceIdentifiersWithoutPermission

שאלות נפוצות

כמה אפליקציות אפשר להוסיף לרשימת ההיתרים ב-CarrierConfig.xml עבור (MCC, ‏ MNC) נתון?

אין הגבלה על מספר גיבובי האישורים שכלולים במערך.

באילו פרמטרים של CarrierConfig ב-CarrierConfig.xml צריך להשתמש כדי להוסיף אפליקציה לרשימת ההיתרים?

משתמשים בפריט ההגדרה ברמה העליונה הבא ב-CarrierConfig.xml הספציפי מתוך אפשרויות ה-AOSP שאתם מגדירים:

<string-array name="carrier_certificate_string_array" num="2">
    <item value="BF02262E5EF59FDD53E57059082F1A7914F284B"/>
    <item value="9F3868A3E1DD19A5311D511A60CF94D975A344B"/>
</string-array>

האם יש תבנית בסיסית של CarrierConfig שאפשר להשתמש בה?

משתמשים בתבנית הבאה. צריך להוסיף אותו ל נכס הרלוונטי.

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<carrier_config>
    <string-array name="carrier_certificate_string_array"
num="1">
        <item value="CERTIFICATE_HASH_HERE"/>
    </string-array>
</carrier_config>

האם כרטיס ה-SIM של הספק צריך להיות במכשיר כדי לגשת למזהי המכשיר?

הערך של CarrierConfig.xml נקבע על סמך כרטיס ה-SIM שמוחדר כרגע. כלומר, אם אפליקציה של ספק X תנסה לקבל הרשאות גישה בזמן שכרטיס ה-SIM של ספק Y מוכנס, המכשיר לא ימצא התאמה ל-hash ויחזיר חריגת אבטחה.

במכשירים עם כמה כרטיסי SIM, לספק מספר 1 יש הרשאות גישה רק לכרטיס SIM מספר 1, ולהפך.

איך ספקי הסלולר ממירים את אישור החתימה של אפליקציה ל-hash?

כדי להמיר אישורי חתימה לגיבוב לפני שמוסיפים אותם ל-CarrierConfig.xml:

  1. ממירים את החתימה של אישור החתימה למערך בייטים באמצעות toByteArray.
  2. משתמשים ב- MessageDigest כדי להמיר את מערך הבייטים למחרוזת גיבוב מסוג byte[].
  3. המרת הגיבוב מ-byte[] לפורמט של מחרוזת הקסדצימלית. לדוגמה, אפשר לעיין ב-IccUtils.java.

    List<String> certHashes = new ArrayList<>();
    PackageInfo pInfo; // Carrier app PackageInfo
    MessageDigest md =
    MessageDigest.getInstance("SHA-256");
    for (Signature signature : pInfo.signatures) {
        certHashes.add(bytesToHexString(md.digest(signature.toByteArray()));
    }
  4. אם certHashes הוא מערך בגודל 2 עם הערך 12345 ו-54321, מוסיפים את הקטע הבא לקובץ התצורה של הספק.

    <string-array name="carrier_certificate_string_array" num="2">
        <item value="12345"/>
        <item value="54321"/>
    </string-array>