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

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

การใช้งาน

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

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

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

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

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

  • หากแอปกําหนดเป้าหมายเป็นเวอร์ชันก่อน Q และไม่ได้รับสิทธิ์ READ_PHONE_STATE ระบบจะเรียกใช้ SecurityException ซึ่งเป็นลักษณะการทํางานปัจจุบันของเวอร์ชันก่อน Q เนื่องจากต้องใช้สิทธิ์นี้เพื่อเรียกใช้ API เหล่านี้
  • หากแอปกําหนดเป้าหมายเป็นเวอร์ชันก่อน Q และมีการให้สิทธิ์ READ_PHONE_STATE แอปจะได้รับค่า Null สําหรับ TelephonyManager API ทั้งหมดและ 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[] เป็นรูปแบบสตริงฐาน 16 ดูตัวอย่างได้ที่ 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>