Môi trường thực thi đáng tin cậy (TEE) có trong hệ thống trên một vi mạch (SoC) mang đến cơ hội cho các thiết bị Android cung cấp các dịch vụ bảo mật mạnh mẽ, dựa trên phần cứng cho hệ điều hành Android, cho các dịch vụ nền tảng và thậm chí cho các ứng dụng bên thứ ba (dưới dạng các tiện ích dành riêng cho Android đối với Kiến trúc mã hoá Java tiêu chuẩn, hãy xem KeyGenParameterSpec
).
Bảng chú giải thuật ngữ
Sau đây là thông tin tổng quan nhanh về các thành phần của Keystore và mối quan hệ giữa chúng.
AndroidKeyStore
- API và thành phần Khung Android mà các ứng dụng dùng để truy cập vào chức năng Kho khoá. Đây là một cách triển khai các API Kiến trúc mật mã Java tiêu chuẩn, nhưng cũng bổ sung các tiện ích dành riêng cho Android và bao gồm mã Java chạy trong không gian quy trình riêng của ứng dụng.
AndroidKeyStore
đáp ứng các yêu cầu của ứng dụng về hành vi của Keystore bằng cách chuyển tiếp các yêu cầu đó đến trình nền keystore. - trình nền kho khoá
- Một trình nền hệ thống Android cung cấp quyền truy cập vào mọi chức năng của Kho khoá thông qua một API Binder. Trình nền này chịu trách nhiệm lưu trữ keyblob do việc triển khai KeyMint (hoặc Keymaster) cơ bản tạo ra. Keyblob chứa nội dung khoá bí mật, được mã hoá để Kho khoá có thể lưu trữ nhưng không sử dụng hoặc tiết lộ nội dung đó.
- Dịch vụ HAL KeyMint
- Một máy chủ AIDL triển khai HAL
IKeyMintDevice
, cung cấp quyền truy cập vào TA KeyMint cơ bản. - Ứng dụng đáng tin cậy (TA) KeyMint
- Phần mềm chạy trong một bối cảnh bảo mật, thường là trong TrustZone trên SoC ARM, cung cấp tất cả các thao tác mã hoá bảo mật. Ứng dụng này có quyền truy cập vào nội dung khoá thô và xác thực tất cả các điều kiện kiểm soát quyền truy cập trên khoá trước khi cho phép sử dụng.
LockSettingsService
- Thành phần hệ thống Android chịu trách nhiệm xác thực người dùng, cả mật khẩu và vân tay. Mặc dù không thuộc Kho khoá, nhưng tính năng này vẫn có liên quan vì Kho khoá hỗ trợ khái niệm về khoá liên kết xác thực: khoá chỉ có thể dùng nếu người dùng đã xác thực.
LockSettingsService
tương tác với TA Gatekeeper và TA Vân tay để lấy mã xác thực. Sau đó, mã này sẽ cung cấp cho trình nền khoá và được TA KeyMint sử dụng. - Gatekeeper TA
- Thành phần chạy trong môi trường bảo mật, chịu trách nhiệm xác thực mật khẩu người dùng và tạo mã thông báo xác thực dùng để chứng minh cho TA KeyMint rằng quá trình xác thực đã được thực hiện cho một người dùng cụ thể tại một thời điểm cụ thể.
- TA vân tay
- Thành phần chạy trong môi trường bảo mật, chịu trách nhiệm xác thực dấu vân tay của người dùng và tạo mã thông báo xác thực dùng để chứng minh cho TA KeyMint rằng một hoạt động xác thực đã được thực hiện cho một người dùng cụ thể tại một thời điểm cụ thể.
Kiến trúc
Android Keystore API và KeyMint HAL cơ bản cung cấp một bộ nguyên hàm mã hoá cơ bản nhưng đầy đủ để cho phép triển khai các giao thức bằng cách sử dụng các khoá được kiểm soát quyền truy cập và được phần cứng hỗ trợ.
HAL KeyMint là một dịch vụ do OEM cung cấp, được dịch vụ Kho khoá dùng để cung cấp các dịch vụ mã hoá dựa trên phần cứng. Để giữ an toàn cho nội dung khoá riêng tư, các hoạt động triển khai HAL không thực hiện bất kỳ thao tác nhạy cảm nào trong không gian người dùng, hoặc thậm chí trong không gian nhân. Thay vào đó, dịch vụ HAL KeyMint chạy trong Android sẽ uỷ quyền các thao tác nhạy cảm cho một TA chạy trong một số loại môi trường bảo mật, thường là bằng cách sắp xếp và huỷ sắp xếp các yêu cầu ở một số định dạng truyền dữ liệu do quá trình triển khai xác định.
Kiến trúc kết quả có dạng như sau:

Hình 1. Quyền truy cập vào KeyMint.
API HAL KeyMint có cấp độ thấp, được các thành phần nội bộ của nền tảng sử dụng và không được cung cấp cho nhà phát triển ứng dụng. API Java cấp cao hơn có sẵn cho các ứng dụng được mô tả trên trang web dành cho Nhà phát triển Android.
Kiểm soát quyền truy cập
Kho khoá Android cung cấp một thành phần trung tâm để lưu trữ và sử dụng các khoá mã hoá dựa trên phần cứng, cho cả ứng dụng và các thành phần hệ thống khác. Do đó, quyền truy cập vào bất kỳ khoá riêng lẻ nào thường chỉ giới hạn ở ứng dụng hoặc thành phần hệ thống đã tạo khoá đó.
Miền kho khoá
Để hỗ trợ chế độ kiểm soát quyền truy cập này, các khoá được xác định cho Keystore bằng một trình mô tả khoá. Bộ mô tả khoá này cho biết một miền mà bộ mô tả thuộc về, cùng với một danh tính trong miền đó.
Các ứng dụng Android truy cập vào Kho khoá bằng Kiến trúc mã hoá Java tiêu chuẩn, xác định các khoá bằng một bí danh chuỗi. Phương thức nhận dạng này ánh xạ đến miền Keystore APP
nội bộ; UID của phương thức gọi cũng được đưa vào để phân biệt các khoá từ các ứng dụng khác nhau, ngăn một ứng dụng truy cập vào khoá của ứng dụng khác.
Về nội bộ, mã khung cũng nhận được một mã nhận dạng khoá bằng số duy nhất sau khi khoá được tải. Mã nhận dạng bằng số này được dùng làm giá trị nhận dạng cho các bộ mô tả khoá trong miền KEY_ID
. Tuy nhiên, hoạt động kiểm soát quyền truy cập vẫn được thực hiện: ngay cả khi một ứng dụng phát hiện thấy mã khoá cho khoá của một ứng dụng khác, ứng dụng đó cũng không thể sử dụng mã khoá này trong trường hợp bình thường.
Tuy nhiên, một ứng dụng có thể cấp quyền sử dụng khoá cho một ứng dụng khác (được xác định bằng UID). Thao tác cấp này trả về một giá trị nhận dạng cấp duy nhất, được dùng làm giá trị nhận dạng cho các bộ mô tả khoá trong miền GRANT
. Một lần nữa, quyền kiểm soát truy cập vẫn được thực hiện: ngay cả khi một ứng dụng thứ ba phát hiện ra mã nhận dạng cấp quyền cho khoá của bên được cấp quyền, ứng dụng đó cũng không thể sử dụng mã nhận dạng này.
Kho khoá cũng hỗ trợ 2 miền khác cho các bộ mô tả khoá. Các miền này được dùng cho các thành phần khác của hệ thống và không dùng được cho các khoá do ứng dụng tạo:
- Miền
BLOB
cho biết không có giá trị nhận dạng cho khoá trong bộ mô tả khoá; thay vào đó, bộ mô tả khoá sẽ giữ chính keyblob và ứng dụng sẽ xử lý việc lưu trữ keyblob. Các ứng dụng (ví dụ:vold
) cần truy cập vào Keystore trước khi phân vùng dữ liệu được gắn sẽ sử dụng phương thức này. - Miền
SELINUX
cho phép các thành phần hệ thống chia sẻ khoá, với quyền truy cập do một giá trị nhận dạng bằng số tương ứng với nhãn SELinux kiểm soát (xem chính sách SELinux cho khoá keystore_key).
Chính sách SELinux cho keystore_key
Các giá trị nhận dạng dùng cho bộ mô tả khoá Domain::SELINUX
được định cấu hình trong tệp chính sách keystore2_key_context
SELinux.
Mỗi dòng trong các tệp này ánh xạ một số đến nhãn SELinux, ví dụ:
# wifi_key is a keystore2_key namespace intended to be used by wpa supplicant and # Settings to share Keystore keys. 102 u:object_r:wifi_key:s0
Một thành phần cần có quyền truy cập vào khoá có mã nhận dạng 102 trong miền SELINUX
phải có chính sách SELinux tương ứng. Ví dụ: để cho phép wpa_supplicant
nhận và sử dụng các khoá này, hãy thêm dòng sau vào hal_wifi_supplicant.te
:
allow hal_wifi_supplicant wifi_key:keystore2_key { get, use };
Giá trị nhận dạng bằng số cho các khoá Domain::SELINUX
được chia thành các dải để hỗ trợ nhiều phân vùng mà không bị xung đột:
Phân vùng | Phạm vi | Tệp cấu hình |
---|---|---|
Hệ thống | 0 ... 9.999 | /system/etc/selinux/keystore2_key_contexts, /plat_keystore2_key_contexts
|
Hệ thống mở rộng | 10.000 ... 19.999 | /system_ext/etc/selinux/system_ext_keystore2_key_contexts, /system_ext_keystore2_key_contexts
|
Sản phẩm | 20.000 ... 29.999 | /product/etc/selinux/product_keystore2_key_contexts, /product_keystore2_key_contexts
|
Nhà cung cấp | 30.000 ... 39.999 | /vendor/etc/selinux/vendor_keystore2_key_contexts, /vendor_keystore2_key_contexts
|
Các giá trị cụ thể sau đây đã được xác định cho phân vùng hệ thống:
ID không gian tên | Nhãn SEPolicy | UID | Mô tả |
---|---|---|---|
0 | su_key |
Không áp dụng | Khoá người dùng cấp cao. Chỉ dùng để kiểm thử trên các bản dựng userdebug và eng. Không liên quan đến các bản dựng người dùng. |
1 | shell_key |
Không áp dụng | Không gian tên có sẵn cho shell. Chủ yếu dùng để kiểm thử, nhưng cũng có thể dùng trên các bản dựng người dùng từ dòng lệnh. |
100 | vold_key |
Không áp dụng | Dành cho vold sử dụng. |
101 | odsign_key |
Không áp dụng | Được trình nền ký trên thiết bị sử dụng. |
102 | wifi_key |
AID_WIFI(1010) |
Được hệ thống con Wifi của Android sử dụng, bao gồm cả wpa_supplicant . |
103 | locksettings_key |
Không áp dụng | Được dùng bởi LockSettingsService |
120 | resume_on_reboot_key |
AID_SYSTEM(1000) |
Được máy chủ hệ thống của Android dùng để hỗ trợ tiếp tục khi khởi động lại. |
Vectơ truy cập
Kho khoá cho phép kiểm soát những thao tác có thể thực hiện trên một khoá, ngoài việc kiểm soát quyền truy cập tổng thể vào một khoá. Các quyền keystore2_key
được mô tả trong tệp KeyPermission.aidl
.
Quyền của hệ thống
Ngoài các chế độ kiểm soát quyền truy cập theo khoá được mô tả trong Chính sách SELinux cho khoá keystore_key, bảng sau đây mô tả các quyền SELinux khác cần thiết để thực hiện nhiều thao tác bảo trì và hệ thống:
Quyền | Ý nghĩa |
---|---|
add_auth
|
Bắt buộc để thêm mã thông báo xác thực vào Kho khoá; được các nhà cung cấp dịch vụ xác thực như Gatekeeper hoặc BiometricManager sử dụng. |
clear_ns
|
Bắt buộc để xoá tất cả các khoá trong một không gian tên cụ thể; được dùng làm thao tác bảo trì khi ứng dụng bị gỡ cài đặt. |
list
|
Hệ thống cần đến các khoá này để liệt kê khoá theo nhiều thuộc tính, chẳng hạn như quyền sở hữu hoặc liệu khoá có được liên kết với quy trình xác thực hay không. Phương thức gọi liệt kê không gian tên của riêng họ không cần có quyền này (được cấp quyền get_info ). |
lock
|
Bắt buộc để thông báo cho kho khoá rằng thiết bị đã bị khoá, từ đó loại bỏ các siêu khoá để đảm bảo rằng các khoá được liên kết với quy trình xác thực không dùng được. |
unlock
|
Bắt buộc phải thông báo cho kho khoá rằng thiết bị đã được mở khoá, khôi phục quyền truy cập vào các siêu khoá bảo vệ các khoá được liên kết với hoạt động xác thực. |
reset
|
Bắt buộc để đặt lại Keystore về chế độ cài đặt gốc, xoá tất cả các khoá không quan trọng đối với hoạt động của hệ điều hành Android. |
Nhật ký
Trong Android 5 trở xuống, Android có một API dịch vụ mật mã đơn giản, dựa trên phần cứng, do các phiên bản 0.2 và 0.3 của lớp trừu tượng phần cứng (HAL) Keymaster cung cấp. Kho khoá cung cấp các thao tác ký và xác minh kỹ thuật số, cộng với việc tạo và nhập các cặp khoá ký bất đối xứng. Điều này đã được triển khai trên nhiều thiết bị, nhưng có nhiều mục tiêu bảo mật không thể dễ dàng đạt được chỉ bằng một API chữ ký. Android 6.0 đã mở rộng Keystore API để cung cấp nhiều chức năng hơn.
Android 6.0
Trong Android 6.0, Keymaster 1.0 đã thêm các nguyên tắc mã hoá đối xứng, AES và HMAC, cũng như một hệ thống kiểm soát quyền truy cập cho các khoá dựa trên phần cứng. Các chế độ kiểm soát quyền truy cập được chỉ định trong quá trình tạo khoá và được thực thi trong suốt thời gian tồn tại của khoá. Bạn có thể hạn chế để chỉ sử dụng được khoá sau khi người dùng đã được xác thực và chỉ cho các mục đích cụ thể hoặc với các thông số mật mã cụ thể.
Ngoài việc mở rộng phạm vi của các nguyên tắc mã hoá, Keystore trong Android 6.0 còn bổ sung những tính năng sau:
- Một sơ đồ kiểm soát việc sử dụng để cho phép giới hạn việc sử dụng khoá, nhằm giảm thiểu nguy cơ bảo mật bị xâm phạm do sử dụng sai khoá
- Một sơ đồ kiểm soát quyền truy cập để cho phép hạn chế khoá đối với những người dùng, ứng dụng và phạm vi thời gian cụ thể
Android 7.0
Trong Android 7.0, Keymaster 2 đã thêm tính năng hỗ trợ chứng thực khoá và liên kết phiên bản.
Chứng thực khoá cung cấp các chứng chỉ khoá công khai có chứa nội dung mô tả chi tiết về khoá và các chế độ kiểm soát quyền truy cập của khoá, để có thể xác minh từ xa sự tồn tại của khoá trong phần cứng bảo mật và cấu hình của khoá.
Liên kết phiên bản liên kết các khoá với hệ điều hành và phiên bản cấp bản vá. Điều này đảm bảo rằng kẻ tấn công phát hiện ra điểm yếu trong phiên bản cũ của hệ thống hoặc phần mềm TEE không thể khôi phục thiết bị về phiên bản dễ bị tấn công và sử dụng các khoá được tạo bằng phiên bản mới hơn. Ngoài ra, khi một khoá có phiên bản và cấp độ bản vá nhất định được dùng trên một thiết bị đã nâng cấp lên phiên bản hoặc cấp độ bản vá mới hơn, khoá đó sẽ được nâng cấp trước khi có thể sử dụng và phiên bản trước của khoá sẽ không hợp lệ. Khi thiết bị được nâng cấp, các khoá sẽ tăng lên cùng với thiết bị, nhưng mọi việc khôi phục thiết bị về một bản phát hành trước đó sẽ khiến các khoá không sử dụng được.
Android 8.0
Trong Android 8.0, Keymaster 3 đã chuyển từ HAL cấu trúc C kiểu cũ sang giao diện HAL C++ được tạo từ một định nghĩa trong ngôn ngữ định nghĩa giao diện phần cứng (HIDL) mới. Trong quá trình thay đổi, nhiều loại đối số đã thay đổi, mặc dù các loại và phương thức có mối tương ứng một-một với các loại cũ và phương thức cấu trúc HAL.
Ngoài bản sửa đổi giao diện này, Android 8.0 còn mở rộng tính năng chứng thực của Keymaster 2 để hỗ trợ chứng thực mã nhận dạng. Chứng thực mã nhận dạng cung cấp một cơ chế có giới hạn và không bắt buộc để chứng thực mạnh mẽ các giá trị nhận dạng phần cứng, chẳng hạn như số sê-ri thiết bị, tên sản phẩm và mã nhận dạng điện thoại (IMEI hoặc MEID). Để triển khai việc bổ sung này, Android 8.0 đã thay đổi giản đồ chứng thực ASN.1 để thêm chứng thực mã nhận dạng. Các hoạt động triển khai Keymaster cần tìm ra một cách an toàn để truy xuất các mục dữ liệu có liên quan, cũng như xác định một cơ chế để tắt tính năng này một cách an toàn và vĩnh viễn.
Android 9
Trong Android 9, các bản cập nhật bao gồm:
- Cập nhật lên Keymaster 4
- Hỗ trợ các Phần tử bảo mật được nhúng
- Hỗ trợ nhập khoá an toàn
- Hỗ trợ mã hoá 3DES
- Thay đổi về việc liên kết phiên bản để
boot.img
vàsystem.img
có các phiên bản được đặt riêng biệt để cho phép cập nhật độc lập
Android 10
Android 10 ra mắt Keymaster HAL phiên bản 4.1, trong đó có thêm:
- Hỗ trợ các khoá chỉ dùng được khi thiết bị ở trạng thái mở khoá
- Hỗ trợ các khoá chỉ có thể dùng trong giai đoạn khởi động ban đầu
- Hỗ trợ không bắt buộc cho các khoá lưu trữ được bao bọc bằng phần cứng
- Hỗ trợ không bắt buộc cho chứng thực duy nhất của thiết bị trong StrongBox
Android 12
Android 12 ra mắt HAL KeyMint mới, thay thế HAL Keymaster nhưng cung cấp chức năng tương tự. Ngoài tất cả các tính năng nêu trên, HAL KeyMint còn bao gồm:
- Hỗ trợ thoả thuận về khoá ECDH
- Hỗ trợ các khoá chứng thực do người dùng chỉ định
- Hỗ trợ các khoá có số lần sử dụng hạn chế
Android 12 cũng có một phiên bản mới của trình nền hệ thống kho khoá, được viết lại bằng Rust và được gọi là keystore2
Android 13
Android 13 đã thêm phiên bản 2 của KeyMint HAL, bổ sung tính năng hỗ trợ Curve25519 cho cả hoạt động ký và thoả thuận khoá.