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

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
  • สร้าง#getSerial

การเข้าถึงสำหรับแอปของผู้ให้บริการที่ไม่มีสิทธิ์ READ_PRIVILEGED_PHONE_STATE

แอปของผู้ให้บริการ ที่โหลดไว้ล่วงหน้า ซึ่งไม่มีคุณสมบัติรับสิทธิ์ READ_PRIVILEGED_PHONE_STATE สามารถใช้ตัวเลือกใดตัวเลือกหนึ่งในตารางด้านล่างได้

ตัวเลือก คำอธิบาย ข้อจำกัด
สิทธิ์ของผู้ให้บริการ UICC แพลตฟอร์ม Android โหลดใบรับรองที่จัดเก็บไว้ใน UICC และให้สิทธิ์แก่แอปที่ลงนามโดยใบรับรองเหล่านี้เพื่อทำการเรียกใช้วิธีการพิเศษ ผู้ให้บริการระบบเดิมมีจำนวน SIM จำนวนมาก ซึ่งไม่สามารถอัปเดตได้ง่าย นอกจากนี้ ผู้ให้บริการที่ไม่มีสิทธิ์ในการเขียนซิมใหม่ (เช่น 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

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

  • หากแอปกำหนดเป้าหมายเป็น pre-Q และไม่มีสิทธิ์ READ_PHONE_STATE SecurityException จะถูกทริกเกอร์ นี่เป็นพฤติกรรมก่อน Q ในปัจจุบัน เนื่องจากจำเป็นต้องได้รับอนุญาตเพื่อเรียกใช้ API เหล่านี้
  • หากแอปกำหนดเป้าหมายเป็น pre-Q และได้รับอนุญาต READ_PHONE_STATE แอปจะได้รับค่าว่างสำหรับ 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 ที่ใช้จะขึ้นอยู่กับ SIM ที่ใส่อยู่ในปัจจุบัน ซึ่งหมายความว่าหากแอปของผู้ให้บริการ X พยายามรับสิทธิ์การเข้าถึงในขณะที่ใส่ซิมของผู้ให้บริการ Y อุปกรณ์จะไม่พบแฮชที่ตรงกันและส่งกลับข้อยกเว้นด้านความปลอดภัย

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

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

หากต้องการแปลงใบรับรองการลงนามเป็นแฮชก่อนที่จะเพิ่มลงใน CarrierConfig.xml ให้ทำดังต่อไปนี้:

  1. แปลงลายเซ็นของใบรับรองการลงนามเป็นอาร์เรย์ไบต์โดยใช้ toByteArray
  2. ใช้ MessageDigest เพื่อแปลงอาร์เรย์ไบต์เป็นแฮชในประเภทไบต์ []
  3. แปลงแฮชจากไบต์[] ให้เป็นรูปแบบสตริงฐานสิบหก ตัวอย่างเช่น โปรดดูที่ 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>