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.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#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:
- 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á. - 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ứ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 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:
- Chuyển đổi chữ ký của chứng chỉ ký thành một mảng byte sử dụng
toByteArray
. - Sử dụng
MessageDigest
để chuyển đổi mảng byte thành một hàm băm trong byte[]. -
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())); }
Nếu
certHashes
là một mảng kích thước2
kèm theo một giá trị về12345
và54321
, 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>