ב-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
. אם נמצאה התאמה, המידע המבוקש מוחזר. אם לא נמצאה התאמה, מוחזרת החרגת אבטחה.
כדי להטמיע את הפתרון הזה, הספקים חייבים לפעול לפי השלבים הבאים:
- מעדכנים את
CarrierConfig.xml
ב-hash של אישור החתימה של אפליקציית הספק ושולחים תיקון. - מבקשים מהיצרנים לעדכן את ה-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
:
- ממירים את החתימה של אישור החתימה למערך בייטים באמצעות
toByteArray
. - משתמשים ב-
MessageDigest
כדי להמיר את מערך הבייטים למחרוזת גיבוב מסוג byte[]. -
המרת הגיבוב מ-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())); }
אם
certHashes
הוא מערך בגודל2
עם הערך12345
ו-54321
, מוסיפים את הקטע הבא לקובץ התצורה של הספק.<string-array name="carrier_certificate_string_array" num="2"> <item value="12345"/> <item value="54321"/> </string-array>