Android 10 thay đổi quyền đối với giá trị nhận dạng thiết bị để tất 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 Android 10, các 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 trong thời gian 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 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.java và Build.java.
Thay đổi này ảnh hưởng đến các API sau:
- TelephonyManager#getDeviceId
- TelephonyManager#getImei
- TelephonyManager#getMeid
- TelephonyManager#getSimSerialNumber
- TelephonyManager#getSubscriberId
- Build#getSerial
Quyền truy cập cho ứng dụng của nhà mạng không có quyền READ_PRIVILEGED_PHONE_STATE
Các ứng dụng của nhà mạng được tải trước không đủ điều kiện để có quyền READ_PRIVILEGED_PHONE_STATE
có thể triển khai một trong các tuỳ chọn trong bảng bên dưới.
Tuỳ chọn | Nội dung mô tả | Giới hạn |
---|---|---|
Đặc quyền của nhà mạng đối với UICC | Nền tảng Android tải các chứng chỉ được lưu trữ trên UICC và cấp quyền cho các ứng dụng do các chứng chỉ này ký để thực hiện lệnh gọi đến các phương thức đặc biệt. | Các nhà mạng cũ có một lượng lớn thẻ SIM đã được thiết lập và khó cập nhật. Ngoài ra, những nhà mạng không có quyền tác giả đối với thẻ SIM mới (ví dụ: MVNO có thẻ SIM do MNO phát hành) không thể thêm hoặc cập nhật chứng chỉ trên thẻ SIM. |
Thêm vào danh sách cho phép của OEM | OEM có thể sử dụng OP_READ_DEVICE_IDENTIFIER để cung cấp giá trị nhận dạng thiết bị cho các ứng dụng của nhà mạng có trong danh sách cho phép. |
Giải pháp này không thể mở rộng cho tất cả các nhà mạng. |
Mã phân bổ loại (TAC) | Sử dụng phương thức getTypeAllocationCode được giới thiệu trong Android 10 để hiển thị TAC trả về thông tin nhà sản xuất và kiểu máy. |
Thông tin trong TAC không đủ để 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 TelephonyManager với nhóm quyền PHONE để tra cứu IMEI trên hệ thống phụ trợ của họ. |
Điều này đòi hỏi các nhà mạng phải đầu tư đáng kể. Những nhà mạng liên kết khoá mạng bằng IMSI cần có nhiều tài nguyên kỹ thuật để chuyển sang MSISDN. |
Tất cả ứng dụng của nhà mạng đều có thể truy cập vào giá trị nhận dạng thiết bị bằng cách cập nhật tệp CarrierConfig.xml
bằng hàm băm chứng chỉ ký của ứ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, nền tảng sẽ tìm kiếm hàm băm chứng chỉ ký của ứng dụng (chữ ký SHA-1 hoặc SHA-256 của chứng chỉ) trong tệp CarrierConfig.xml
. Nếu tìm thấy kết quả trùng khớp, thông tin được yêu cầu sẽ được trả về. Nếu không tìm thấy kết quả trùng khớp, hệ thống sẽ trả về một trường hợp ngoại lệ về bảo mật.
Để triển khai giải pháp này, nhà mạng PHẢI làm theo các bước sau:
- Cập nhật
CarrierConfig.xml
bằng hàm băm chứng chỉ ký của ứng dụng của nhà mạng và gửi bản vá. - Yêu cầu nhà sản xuất thiết bị gốc (OEM) cập nhật bản dựng bằng QPR1 trở lên (nên dùng) HOẶC các bản vá nền tảng bắt buộc này và bản vá chứa tệp
CarrierConfig.xml
đã cập nhật từ bước 1 ở trên.
Triển khai
Cập nhật danh sách cho phép quyền đặc quyền để cấp quyền READ_PRIVILEGED_PHONE_STATE
cho những ứng dụng đặc quyền cần quyền truy cập vào giá trị 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 bài viết Danh sách cho phép quyền đặc quyền.
Để gọi các API bị ảnh hưởng, ứng dụng phải đáp ứng một trong các yêu cầu sau:
- Nếu là ứng dụng đặc quyền được tải sẵn, thì ứng dụng cần có quyền
READ_PRIVILEGED_PHONE_STATE
được khai báo trong AndroidManifest.xml. Ứng dụng cũng cần đưa quyền đặc quyền này vào danh sách cho phép. - Các ứng dụng được phân phối thông qua Google Play cần có đặc quyền của nhà cung cấp dịch vụ. Tìm hiểu thêm về cách cấp đặc quyền cho nhà mạng trên trang Đặc quyền của nhà mạng trên UICC.
- Ứng dụng của chủ sở hữu thiết bị hoặc hồ sơ đã được cấp 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 sẽ có hành vi sau:
- Nếu ứng dụng đang nhắm đến phiên bản trước Q và không được cấp quyền
READ_PHONE_STATE
, thìSecurityException
sẽ được kích hoạt. Đây là hành vi hiện tại trước Q vì quyền này là bắt buộc để gọi các API này. - Nếu ứng dụng đang nhắm đến phiên bản trước Q và được cấp quyền
READ_PHONE_STATE
, thì ứng dụng đó sẽ nhận được giá trị rỗng cho tất cả API TelephonyManager vàBuild.UNKNOWN
cho phương thứcBuild#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 một SecurityException.
Xác thực và kiểm thử
Bộ kiểm thử tính tương thích (CTS) bao gồm các kiểm thử để xác minh hành vi truy cập giá trị nhận dạng thiết bị dự kiến cho các ứng dụng có đặc quyền của nhà mạng, chủ sở hữu thiết bị và hồ sơ, cũng như những ứng dụng dự kiến sẽ không có quyền truy cập vào giá trị nhận dạng thiết bị.
Các 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
Một (MCC, MNC) có thể thêm bao nhiêu ứng dụng vào danh sách cho phép trong CarrierConfig.xml
?
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 sử dụng thông số CarrierConfig nào trong CarrierConfig.xml
để ứ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 CarrierConfig.xml
cụ thể từ 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>
Tôi có thể sử dụng mẫu CarrierConfig cơ sở nào không?
Sử dụng mẫu sau. Bạn nên thêm thông tin này vào thành phần liên quan.
<?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>
Có phải phải lắp thẻ SIM của nhà mạng vào thiết bị thì mới có thể truy cập vào giá trị nhận dạng thiết bị không?
CarrierConfig.xml
được sử dụng được xác định dựa trên thẻ SIM đang được lắp. Điều này có nghĩa 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 thẻ SIM của nhà mạng Y được lắp vào, thì thiết bị sẽ không tìm thấy
kết quả trùng khớp cho hàm băm và trả về một ngoại lệ bảo mật.
Trên thiết bị nhiều SIM, nhà mạng #1 chỉ có đặc quyền truy cập vào SIM #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 như thế nào?
Để chuyển đổi chứng chỉ ký thành hàm băm trước khi thêm các chứng chỉ đó vào CarrierConfig.xml
, hãy làm như sau:
- Chuyển đổi chữ ký của chứng chỉ ký thành một mảng byte bằng cách sử dụng
toByteArray
. - Sử dụng
MessageDigest
để chuyển đổi mảng byte thành hàm băm trong loại byte[]. -
Chuyển đổi hàm băm từ byte[] sang định dạng chuỗi thập lục phân. Để biết ví dụ, hãy 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())); }
Nếu
certHashes
là một mảng có kích thước2
với giá trị là12345
và54321
, hãy thêm nội dung 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>