Mã nhận dạng thiết bị

Android 10 thay đổi quyền cho để tất cả các giá trị nhận dạng thiết bị hiện được bảo vệ bằng quyền READ_PRIVILEGED_PHONE_STATE. Trước khi Android 10, giá trị nhận dạng thiết bị cố định (IMEI/MEID, IMSI, SIM và số sê-ri bản dựng) được bảo vệ bằng Quyền khi bắt đầu chạy READ_PHONE_STATE. Quyền READ_PRIVILEGED_PHONE_STATE chỉ được cấp cho các ứng dụng được ký bằng khoá nền tảng và các ứng dụng hệ thống có đặc quyền.

Bạn có thể xem thêm thông tin về các yêu cầu mới về quyền trong Các trang Javadoc cho TelephonyManager.javaBuild.java.

Thay đổi này ảnh hưởng đến các API sau:

  • TelephonyManager#getDeviceId
  • TelephonyManager#getImei
  • TelephonyManager#getMeid
  • TelephonyManager#getSimSerialNumber
  • TelephonyManager#getSubscriptionsId
  • Bản dựng#getSerial

Quyền truy cập vào các ứng dụng của nhà mạng mà không cần quyền READ_PRIVILEGED_PHONE_STATE

Các ứng dụng được tải trước của nhà mạng không đủ điều kiện cho READ_PRIVILEGED_PHONE_STATE có thể triển khai một trong các tuỳ chọn trong bảng bên dưới.

Lựa chọn Mô tả Giới hạn
Đặc quyền của nhà mạng UICC Nền tảng Android tải các chứng chỉ lưu trữ trên UICC và cấp quyền truy cập vào các ứng dụng được ký bởi các chứng chỉ này để thực hiện cuộc gọi đến . Các nhà mạng cũ có lượng người dùng SIM lớn và ổn định dễ cập nhật. Ngoài ra, các nhà mạng không có quyền uỷ quyền đối với Bạn không thể thêm hoặc thêm SIM (ví dụ: MVNO có SIM do các MNO phát hành) hãy cập nhật chứng chỉ trên SIM.
Đưa OEM vào danh sách cho phép OEM có thể sử dụng OP_READ_DEVICE_IDENTIFIER để cung cấp thiết bị giá trị nhận dạng cho các ứng dụng của nhà mạng trong danh sách cho phép. Không phải nhà mạng nào cũng có thể sử dụng giải pháp này.
Mã phân bổ loại (TAC) Sử dụng getTypeAllocationCode được giới thiệu trong Android 10, để hiển thị TAC trả về nhà sản xuất và kiểu máy của bạn. Thông tin trong TAC không đầy đủ để xác định một thiết bị cụ thể.
MSISDN Nhà mạng có thể sử dụng số điện thoại (MSISDN), có trong phần TelephonyManager có quyền PHONE để tra cứu số IMEI trên hệ thống phụ trợ của họ. Để làm được việc này, các nhà mạng phải đầu tư đáng kể. Các hãng vận chuyển dựa trên bản đồ các khoá mạng của họ bằng IMSI đòi hỏi rất nhiều để chuyển sang sử dụng MSISDN.

Tất cả ứng dụng của nhà mạng đều có thể truy cập vào mã nhận dạng thiết bị bằng cách cập nhật tệp CarrierConfig.xml có hàm băm chứng chỉ ký là ứng dụng của nhà mạng. Khi ứng dụng của nhà mạng gọi một phương thức để đọc thông tin đặc quyền thông tin, nền tảng sẽ tìm kết quả trùng khớp của chứng chỉ ký của ứng dụng (chữ ký SHA-1 hoặc SHA-256 của chứng chỉ) trong CarrierConfig.xml. Nếu tìm thấy kết quả trùng khớp, thì URL được yêu cầu sẽ được trả về. Nếu không tìm thấy kết quả trùng khớp, thì một ngoại lệ về bảo mật sẽ là bị trả lại.

Để triển khai giải pháp này, nhà mạng PHẢI làm theo các bước sau:

  1. Nội dung cập nhật CarrierConfig.xml với hàm băm chứng chỉ ký của ứng dụng của nhà mạng và gửi bản vá.
  2. Yêu cầu OEM cập nhật bản dựng bằng QPR1+ (nên dùng) HOẶC các bản vá nền tảng bắt buộc và bản vá có chứa đã cập nhật tệp CarrierConfig.xml trong bước 1 ở trên.

Triển khai

Cập nhật danh sách cho phép các quyền có đặc quyền để cấp Quyền READ_PRIVILEGED_PHONE_STATE cho những người có đặc quyền những ứng dụng yêu cầu quyền truy cập vào mã nhận dạng thiết bị.

Để tìm hiểu thêm về danh sách cho phép, hãy tham khảo phần Được đặc quyền Liệt kê quyền cho phép.

Để gọi các API bị ảnh hưởng, ứng dụng phải đáp ứng một trong các điều kiện sau các yêu cầu:

  • Nếu là một ứng dụng có đặc quyền được tải trước, ứng dụng đó cần Đã khai báo quyền READ_PRIVILEGED_PHONE_STATE trong Tệp AndroidManifest.xml. Ứng dụng cũng cần đưa vào danh sách cho phép quyền đặc quyền này.
  • Ứng dụng được phân phối qua Google Play cần có đặc quyền của nhà mạng. Tìm hiểu thêm về cách cấp đặc quyền của nhà mạng trên Nhà mạng UICC trang Đặc quyền.
  • Ứng dụng chủ sở hữu thiết bị hoặc hồ sơ đã được cấp quyền Quyền READ_PHONE_STATE.

Ứng dụng không đáp ứng bất kỳ yêu cầu nào trong số này có: hành vi:

  • Nếu ứng dụng đang nhắm mục tiêu đến trước quý và không có Đã cấp quyền READ_PHONE_STATE, SecurityException được kích hoạt. đây là hành vi trước khi trả lời hiện tại giống như quyền này được yêu cầu để gọi các API này.
  • Nếu ứng dụng đang nhắm mục tiêu đến trước quý và có Đã cấp READ_PHONE_STATE quyền, ứng dụng sẽ nhận được một giá trị rỗng cho tất cả API TelephonyManager và Build.UNKNOWN cho phương thức Build#getSerial.
  • Nếu ứng dụng nhắm đến Android 10 trở lên và không đáp ứng bất kỳ yêu cầu mới nào thì ứng dụng sẽ nhận được SecurityException.

Xác thực và kiểm thử

Thẻ Tương thích Bộ kiểm thử (CTS) bao gồm các bài kiểm thử để xác minh mã nhận dạng thiết bị dự kiến hành vi truy cập đối với ứng dụng có đặc quyền của nhà mạng, thiết bị và chủ sở hữu hồ sơ và những ứng dụng dự kiến không có quyền truy cập vào thiết bị giá trị nhận dạng.

Các bài kiểm thử CTS sau đây dành riêng cho tính năng này.

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

Câu hỏi thường gặp

Có bao nhiêu ứng dụng có thể được đưa vào danh sách cho phép tại CarrierConfig.xml đối với một tài khoản người quản lý (MCC, MNC) cụ thể?

Không có giới hạn về số lượng hàm băm chứng chỉ có trong mảng.

Tôi cần dùng thông số nào của ProviderConfig trong CarrierConfig.xml để một ứng dụng được đưa vào danh sách cho phép?

Sử dụng mục cấu hình cấp cao nhất sau đây trong phần CarrierConfig.xml trong các tuỳ chọn AOSP mà bạn đang định cấu hình:

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

Có mẫu ProviderConfig cơ sở nào mà tôi có thể sử dụng không?

Hãy sử dụng mẫu sau. Bạn nên thêm thông tin này vào thành phần phù hợp.

<?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>

Thiết bị có cần phải lắp SIM của nhà mạng để truy cập vào mã nhận dạng thiết bị không?

CarrierConfig.xml được sử dụng được xác định dựa trên SIM hiện đang lắp. Tức là nếu ứng dụng của nhà mạng X cố gắng nhận đặc quyền truy cập trong khi lắp SIM của nhà mạng Y nhưng thiết bị sẽ không tìm thấy kết quả phù hợp cho hàm băm và trả về một ngoại lệ về bảo mật.

Trên các thiết bị có nhiều SIM, nhà mạng số 1 chỉ có đặc quyền truy cập đối với SIM số 1 và ngược lại.

Nhà mạng chuyển đổi chứng chỉ ký của ứng dụng thành hàm băm bằng cách nào?

Để chuyển đổi chứng chỉ ký thành hàm băm trước khi thêm chứng chỉ vào CarrierConfig.xml, hãy làm như sau:

  1. Chuyển đổi chữ ký của chứng chỉ ký thành một mảng byte sử dụng toByteArray.
  2. Sử dụng MessageDigest để chuyển đổi mảng byte thành một hàm băm trong byte[].
  3. Chuyển đổi hàm băm từ byte[] thành định dạng chuỗi hex. Ví dụ: xem 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. Nếu certHashes là một mảng kích thước 2 kèm theo một giá trị về 1234554321, hãy thêm đoạn mã sau vào tệp cấu hình của nhà mạng.

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