ตัวระบุอุปกรณ์

Android 10 เปลี่ยนสิทธิ์สำหรับตัวระบุอุปกรณ์เพื่อให้ตัวระบุอุปกรณ์ทั้งหมดได้รับการปกป้องโดยสิทธิ์ READ_PRIVILEGED_PHONE_STATE ก่อน Android 10 ตัวระบุอุปกรณ์ถาวร (IMEI/MEID, IMSI, SIM และซีเรียลของบิลด์) ได้รับการปกป้องภายใต้ 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 และให้สิทธิ์แก่แอปที่รับรองโดยใบรับรองเหล่านี้เพื่อเรียกใช้เมธอดพิเศษ ผู้ให้บริการเดิมมีซิมจำนวนมากที่ใช้งานอยู่ ซึ่งอัปเดตได้ยาก นอกจากนี้ ผู้ให้บริการที่ไม่มีสิทธิ์ในการเขียนซิมใหม่ (เช่น MVNO ที่มีซิมที่ออกโดย MNO) จะเพิ่มหรืออัปเดตใบรับรองในซิมไม่ได้
การอนุญาต OEM 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 ด้วยแฮชใบรับรองการลงนามของ แอปของผู้ให้บริการ และ ส่งแพตช์
  2. ขอให้ OEM อัปเดตบิลด์ด้วย QPR-1 ขึ้นไป (แนะนำ) หรือแพตช์แพลตฟอร์มที่จำเป็นเหล่านี้และแพตช์ที่มีไฟล์ CarrierConfig.xml ที่อัปเดตจากขั้นตอนที่ 1 ด้านบน

การใช้งาน

อัปเดตรายการที่อนุญาตสำหรับสิทธิ์ที่มีสิทธิ์เพื่อมอบสิทธิ์ READ_PRIVILEGED_PHONE_STATE ให้กับแอปที่มีสิทธิ์เหล่านั้นซึ่งจำเป็นต้องเข้าถึงตัวระบุอุปกรณ์

ดูข้อมูลเพิ่มเติมเกี่ยวกับการเพิ่มลงในรายการที่อนุญาตได้ที่การเพิ่มสิทธิ์พิเศษลงในรายการที่อนุญาต

หากต้องการเรียกใช้ API ที่ได้รับผลกระทบ แอปต้องมีคุณสมบัติตรงตามข้อกำหนดข้อใดข้อหนึ่งต่อไปนี้

  • หากแอปเป็นแอปที่มีสิทธิ์ที่โหลดไว้ล่วงหน้า แอปจะต้องมี READ_PRIVILEGED_PHONE_STATE สิทธิ์ที่ประกาศไว้ใน AndroidManifest.xml นอกจากนี้ แอปยังต้องอยู่ในรายการที่อนุญาต สำหรับสิทธิ์ที่มีสิทธิ์ระดับสูงนี้ด้วย
  • แอปที่นำส่งผ่าน Google Play ต้องมีสิทธิ์ของผู้ให้บริการ ดูข้อมูลเพิ่มเติมเกี่ยวกับการให้สิทธิ์ของผู้ให้บริการในหน้าสิทธิ์ของผู้ให้บริการ UICC
  • แอปเจ้าของอุปกรณ์หรือโปรไฟล์ที่ได้รับสิทธิ์ READ_PHONE_STATE

แอปที่ไม่เป็นไปตามข้อกำหนดเหล่านี้จะมีลักษณะการทำงานดังนี้

  • หากแอปกำหนดเป้าหมายเป็น Android เวอร์ชันก่อน Q และไม่มีสิทธิ์ READ_PHONE_STATE ระบบจะทริกเกอร์ SecurityException ซึ่งเป็นลักษณะการทำงานปัจจุบันของ Android เวอร์ชันก่อน 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>

ต้องใส่ซิมของผู้ให้บริการในอุปกรณ์เพื่อเข้าถึงตัวระบุอุปกรณ์ไหม

CarrierConfig.xml ที่ใช้จะพิจารณาจากซิมที่ใส่อยู่ในปัจจุบัน ซึ่งหมายความว่าหากแอปของผู้ให้บริการ X พยายาม รับสิทธิ์เข้าถึงขณะที่ใส่ซิมของผู้ให้บริการ Y อุปกรณ์จะไม่พบ แฮชที่ตรงกันและจะแสดงข้อยกเว้นด้านความปลอดภัย

ในอุปกรณ์แบบหลายซิม ผู้ให้บริการ #1 จะมีสิทธิ์เข้าถึงเฉพาะซิม #1 และ ในทางกลับกัน

ผู้ให้บริการแปลงใบรับรองการลงนามของแอปเป็นแฮชได้อย่างไร

หากต้องการแปลงใบรับรองการลงนามเป็นแฮชก่อนเพิ่มลงใน 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>