Trang này chứa thông tin về các tính năng mã hoá của Kho khoá Android, do quá trình triển khai KeyMint (hoặc Keymaster) cơ bản cung cấp.
Nguyên hàm mật mã
Kho khoá cung cấp các danh mục thao tác sau:
- Tạo khoá, dẫn đến việc chỉ môi trường bảo mật mới có thể truy cập vào nội dung khoá riêng tư hoặc khoá bí mật. Ứng dụng có thể tạo khoá theo các cách sau:
- Tạo khoá mới
- Nhập tài liệu khoá chưa mã hoá
- Nhập tài liệu khoá đã mã hoá
- Chứng thực khoá: Quá trình tạo khoá bất đối xứng sẽ tạo một chứng chỉ chứa phần khoá công khai của cặp khoá. Giấy chứng nhận này cũng có thể chứa thông tin về siêu dữ liệu cho khoá và trạng thái của thiết bị, tất cả đều được ký bằng một chuỗi khoá quay lại một gốc đáng tin cậy.
- Thao tác mã hoá:
- Mã hoá và giải mã đối xứng (AES, 3DES)
- Giải mã bất đối xứng (RSA)
- Ký bất đối xứng (ECDSA, RSA)
- Ký và xác minh đối xứng (HMAC)
- Thoả thuận khoá bất đối xứng (ECDH)
Xin lưu ý rằng Kho khoá và KeyMint không xử lý các thao tác khoá công khai cho khoá bất đối xứng.
Các phần tử giao thức, chẳng hạn như mục đích, chế độ và khoảng đệm, cũng như các quy tắc ràng buộc kiểm soát quyền truy cập, được chỉ định khi khoá được tạo hoặc nhập và được liên kết vĩnh viễn với khoá, đảm bảo khoá không thể được sử dụng theo bất kỳ cách nào khác.
Các nguyên hàm và chế độ mà quá trình triển khai KeyMint phải hỗ trợ được mô tả trong quy cách giao diện HAL IKeyMintDevice
.
Quá trình triển khai KeyMint cơ bản phải thực hiện việc tạo số ngẫu nhiên để hỗ trợ việc tạo khoá và tạo vùng đệm ngẫu nhiên hoặc vectơ khởi tạo (IV). Để hỗ trợ việc này, hệ thống Android định kỳ cung cấp thêm entropy cho quá trình triển khai KeyMint.
Kiểm soát quyền truy cập vào khoá
Các khoá dựa trên phần cứng không bao giờ có thể được trích xuất từ thiết bị sẽ không mang lại nhiều tính bảo mật nếu kẻ tấn công có thể sử dụng các khoá đó theo ý muốn (mặc dù các khoá này an toàn hơn so với các khoá có thể bị rò rỉ). Do đó, điều quan trọng là Kho khoá phải thực thi các biện pháp kiểm soát quyền truy cập.
Chế độ kiểm soát quyền truy cập được xác định là "danh sách uỷ quyền" của các cặp thẻ/giá trị. Thẻ uỷ quyền là số nguyên 32 bit và giá trị là nhiều loại. Một số thẻ có thể được lặp lại để chỉ định nhiều giá trị. Liệu một thẻ có thể được lặp lại hay không được chỉ định trong giao diện HAL KeyMint (trước đây là Keymaster).
Các giá trị thẻ được hỗ trợ được xác định trong tệp Tag.aidl
và mỗi giá trị được liên kết với một TagType
cho biết loại giá trị được liên kết (ví dụ: số nguyên hoặc byte) và liệu giá trị đó có thể được lặp lại để chỉ định nhiều giá trị được hỗ trợ hay không.
Khi KeyMint tạo một khoá, phương thức gọi sẽ chỉ định một danh sách uỷ quyền cho khoá đó. Danh sách này được Keystore và KeyMint sửa đổi để thêm các quy tắc ràng buộc bổ sung, đồng thời quá trình triển khai KeyMint cơ bản sẽ mã hoá danh sách uỷ quyền cuối cùng vào keyblob được trả về. Danh sách uỷ quyền đã mã hoá được liên kết bằng phương thức mã hoá vào keyblob, do đó, mọi nỗ lực sửa đổi danh sách uỷ quyền (bao gồm cả việc sắp xếp) đều dẫn đến một keyblob không hợp lệ không thể dùng cho các thao tác mã hoá.
Thực thi bằng phần cứng so với thực thi bằng phần mềm
Không phải tất cả các phương thức triển khai phần cứng bảo mật đều có cùng các tính năng. Để hỗ trợ nhiều phương pháp, KeyMint phân biệt giữa việc thực thi kiểm soát quyền truy cập an toàn và không an toàn, hoặc thực thi phần cứng và phần mềm tương ứng.
Thông tin này được hiển thị trong API KeyMint với trường securityLevel
thuộc loại KeyCharacteristics
. Phần cứng bảo mật chịu trách nhiệm đặt các quyền uỷ quyền trong KeyCharacteristics
ở mức độ bảo mật thích hợp, dựa trên những gì phần cứng có thể thực thi. Thông tin này cũng được hiển thị trong bản ghi chứng thực cho khoá bất đối xứng: các đặc điểm chính của SecurityLevel::TRUSTED_ENVIRONMENT
hoặc SecurityLevel::STRONGBOX
xuất hiện trong danh sách hardwareEnforced
và các đặc điểm của SecurityLevel::SOFTWARE
hoặc SecurityLevel::KEYSTORE
xuất hiện trong danh sách softwareEnforced
.
Ví dụ: các quy tắc ràng buộc về khoảng thời gian và ngày mà bạn có thể sử dụng khoá thường không được môi trường bảo mật thực thi, vì môi trường này không có quyền truy cập đáng tin cậy vào thông tin ngày và giờ. Do đó, các hoạt động uỷ quyền như Tag::ORIGINATION_EXPIRE_DATETIME
sẽ được Kho khoá trong Android thực thi và sẽ có SecurityLevel::KEYSTORE
.
Để biết thêm thông tin về cách xác định xem khoá và quyền uỷ quyền của khoá có được hỗ trợ phần cứng hay không, hãy xem phần Chứng thực khoá.
Uỷ quyền tạo thông điệp mã hoá
Các thẻ sau đây được dùng để xác định các đặc điểm mã hoá của các thao tác bằng cách sử dụng khoá liên kết:
Tag::ALGORITHM
Tag::KEY_SIZE
Tag::BLOCK_MODE
Tag::PADDING
Tag::CALLER_NONCE
Tag::DIGEST
Tag::MGF_DIGEST
Các thẻ sau đây có thể lặp lại, nghĩa là nhiều giá trị có thể được liên kết với một khoá duy nhất:
Tag::BLOCK_MODE
Tag::PADDING
Tag::DIGEST
Tag::MGF_DIGEST
Giá trị sẽ được sử dụng được chỉ định tại thời điểm thực hiện phép toán.
Mục đích
Khoá có một tập hợp các mục đích liên quan, được biểu thị dưới dạng một hoặc nhiều mục nhập uỷ quyền có thẻ Tag::PURPOSE
, xác định cách sử dụng các mục nhập đó. Các mục đích được xác định trong KeyPurpose.aidl
.
Xin lưu ý rằng một số tổ hợp giá trị mục đích sẽ gây ra vấn đề bảo mật. Ví dụ: khoá RSA có thể dùng để mã hoá và ký cho phép kẻ tấn công có thể thuyết phục hệ thống giải mã dữ liệu tuỳ ý để tạo chữ ký.
Nhập khoá
KeyMint hỗ trợ nhập:
- Cặp khoá bất đối xứng ở định dạng PKCS#8 được mã hoá DER (không có tính năng mã hoá dựa trên mật khẩu)
- Khoá đối xứng dưới dạng byte thô
Để đảm bảo có thể phân biệt các khoá đã nhập với các khoá được tạo một cách an toàn, Tag::ORIGIN
được đưa vào danh sách uỷ quyền khoá thích hợp. Ví dụ: nếu một khoá được tạo trong phần cứng bảo mật, thì Tag::ORIGIN
có giá trị KeyOrigin::GENERATED
sẽ được tìm thấy trong danh sách hw_enforced
của các đặc điểm khoá, trong khi khoá được nhập vào phần cứng bảo mật sẽ có giá trị KeyOrigin::IMPORTED
.
Xác thực người dùng
Các phương thức triển khai KeyMint bảo mật không triển khai quy trình xác thực người dùng, mà phụ thuộc vào các ứng dụng đáng tin cậy khác có triển khai quy trình này. Để biết giao diện mà các ứng dụng này triển khai, hãy xem trang Gatekeeper.
Các yêu cầu xác thực người dùng được chỉ định thông qua hai nhóm thẻ. Tập hợp đầu tiên cho biết những phương thức xác thực cho phép sử dụng khoá:
Tag::USER_SECURE_ID
có giá trị số 64 bit chỉ định mã nhận dạng người dùng bảo mật được cung cấp trong mã xác thực bảo mật để mở khoá sử dụng khoá. Nếu lặp lại, bạn có thể sử dụng khoá nếu bất kỳ giá trị nào được cung cấp trong mã xác thực bảo mật.
Tập hợp thứ hai cho biết liệu người dùng có cần được xác thực hay không và khi nào cần xác thực.
Nếu không có thẻ nào trong số này nhưng có Tag::USER_SECURE_ID
, thì bạn phải xác thực mỗi khi sử dụng khoá.
Tag::NO_AUTHENTICATION_REQUIRED
cho biết không cần xác thực người dùng, mặc dù quyền truy cập vào khoá vẫn chỉ dành cho ứng dụng sở hữu khoá (và mọi ứng dụng mà ứng dụng đó cấp quyền truy cập).Tag::AUTH_TIMEOUT
là một giá trị số chỉ định (tính bằng giây) mức độ mới của thông tin xác thực người dùng để cho phép sử dụng khoá. Thời gian chờ không vượt quá số lần khởi động lại; sau khi khởi động lại, tất cả các lượt xác thực sẽ không hợp lệ. Bạn có thể đặt thời gian chờ thành một giá trị lớn để cho biết rằng bạn phải xác thực một lần mỗi khi khởi động (2^32 giây là khoảng 136 năm; có thể giả định rằng các thiết bị Android được khởi động lại thường xuyên hơn thế).
Yêu cầu thiết bị đã mở khoá
Bạn chỉ có thể sử dụng các khoá có Tag::UNLOCKED_DEVICE_REQUIRED
khi thiết bị được mở khoá. Để biết ngữ nghĩa chi tiết, hãy xem
KeyProtection.Builder#setUnlockedDeviceRequired(boolean)
.
UNLOCKED_DEVICE_REQUIRED
do Kho khoá thực thi, chứ không phải KeyMint. Tuy nhiên, trong Android 12 trở lên, Kho khoá sẽ mã hoá để bảo vệ khoá UNLOCKED_DEVICE_REQUIRED
khi thiết bị bị khoá nhằm đảm bảo rằng trong hầu hết các trường hợp, không thể sử dụng các khoá đó ngay cả khi Kho khoá bị xâm phạm khi thiết bị bị khoá.
Để đạt được điều này, Kho khoá "mã hoá siêu cấp" tất cả các khoá UNLOCKED_DEVICE_REQUIRED
trước khi lưu trữ các khoá đó trong cơ sở dữ liệu của kho khoá. Khi có thể, kho khoá sẽ bảo vệ các khoá siêu mã hoá (khoá siêu) trong khi thiết bị bị khoá theo cách chỉ có thể khôi phục các khoá đó khi mở khoá thiết bị thành công. (Thuật ngữ "mã hoá siêu cấp" được sử dụng vì lớp mã hoá này được áp dụng bên cạnh lớp mã hoá mà KeyMint đã áp dụng cho tất cả khoá.)
Mỗi người dùng (bao gồm cả hồ sơ)
có hai khoá siêu cấp liên kết với UNLOCKED_DEVICE_REQUIRED
:
- Khoá siêu đối xứng UnlockedDeviceRequired. Đây là khoá AES‑256‑GCM. Phương thức này mã hoá các khoá
UNLOCKED_DEVICE_REQUIRED
được nhập hoặc tạo trong khi thiết bị được mở khoá cho người dùng. - Khoá siêu bất đối xứng UnlockedDeviceRequired. Đây là một cặp khoá ECDH P‑521. Phương thức này mã hoá các khoá
UNLOCKED_DEVICE_REQUIRED
được nhập hoặc tạo trong khi thiết bị bị khoá đối với người dùng. Các khoá được mã hoá bằng khoá bất đối xứng này sẽ được mã hoá lại bằng khoá đối xứng trong lần sử dụng đầu tiên (chỉ có thể xảy ra khi thiết bị đang mở khoá).
Kho khoá tạo các khoá siêu cấp này tại thời điểm tạo người dùng và lưu trữ các khoá đó trong cơ sở dữ liệu, được mã hoá bằng mật khẩu tổng hợp của người dùng. Điều này cho phép khôi phục các tệp bằng mã PIN, hình mở khoá hoặc mật khẩu tương đương.
Kho khoá cũng lưu các khoá siêu này vào bộ nhớ đệm, cho phép hoạt động trên các khoá UNLOCKED_DEVICE_REQUIRED
. Tuy nhiên, phương thức này chỉ cố gắng lưu các phần bí mật của các khoá này vào bộ nhớ đệm khi thiết bị được mở khoá cho người dùng. Khi thiết bị bị khoá cho người dùng, Kho khoá sẽ đặt giá trị rỗng cho bản sao lưu trong bộ nhớ đệm của các phần bí mật của các khoá siêu này (nếu có thể). Cụ thể, khi thiết bị được khoá cho người dùng, Kho khoá sẽ chọn và áp dụng một trong ba cấp độ bảo vệ cho khoá siêu UnlockedDeviceRequired của người dùng:
- Nếu người dùng chỉ bật mã PIN, hình mở khoá hoặc mật khẩu, thì Kho khoá sẽ đặt các phần bí mật của khoá siêu cấp được lưu vào bộ nhớ đệm về giá trị 0. Điều này khiến các khoá siêu cấp chỉ có thể khôi phục được thông qua bản sao đã mã hoá trong cơ sở dữ liệu mà chỉ có thể giải mã bằng mã PIN, hình mở khoá hoặc mật khẩu tương đương.
- Nếu người dùng chỉ có dữ liệu sinh trắc học loại 3 ("mạnh") và đã bật mã PIN, hình mở khoá hoặc mật khẩu, thì Kho khoá sẽ sắp xếp để khoá siêu cấp có thể khôi phục bằng bất kỳ dữ liệu sinh trắc học loại 3 nào (thường là vân tay) mà người dùng đã đăng ký, thay cho mã PIN, hình mở khoá hoặc mật khẩu tương đương. Để thực hiện việc này, ứng dụng sẽ tạo một khoá AES‑256‑GCM mới, mã hoá các phần bí mật của khoá siêu cấp bằng khoá này, nhập khoá AES‑256‑GCM vào KeyMint dưới dạng khoá liên kết sinh trắc học yêu cầu xác thực sinh trắc học thành công trong vòng 15 giây qua và đặt các bản sao văn bản thô của tất cả các khoá này về giá trị 0.
- Nếu người dùng có thông tin sinh trắc học loại 1 ("thuận tiện"), thông tin sinh trắc học loại 2 ("yếu") hoặc đã bật tác nhân tin cậy mở khoá đang hoạt động, thì Kho khoá sẽ lưu các khoá siêu cấp vào bộ nhớ đệm ở dạng văn bản thô. Trong trường hợp này, tính năng bảo mật mã hoá cho khoá
UNLOCKED_DEVICE_REQUIRED
sẽ không được cung cấp. Người dùng có thể tránh phương thức dự phòng kém an toàn này bằng cách không bật các phương thức mở khoá này. Các phương thức mở khoá phổ biến nhất thuộc các danh mục này là mở khoá bằng khuôn mặt trên nhiều thiết bị và mở khoá bằng đồng hồ thông minh đã ghép nối.
Khi người dùng mở khoá thiết bị, Kho khoá sẽ khôi phục khoá siêu UnlockedDeviceRequired của người dùng nếu có thể. Đối với phương thức mở khoá tương đương bằng mã PIN, hình mở khoá hoặc mật khẩu, phương thức này sẽ giải mã bản sao của các khoá này được lưu trữ trong cơ sở dữ liệu. Nếu không, ứng dụng sẽ kiểm tra xem có lưu bản sao của các khoá này được mã hoá bằng khoá liên kết sinh trắc học hay không, nếu có thì sẽ cố gắng giải mã khoá đó. Thao tác này chỉ thành công nếu người dùng đã xác thực thành công bằng thông tin sinh trắc học loại 3 trong vòng 15 giây qua, do KeyMint (không phải Kho khoá) thực thi.
Liên kết ứng dụng
Liên kết ứng dụng khách, liên kết một khoá với một ứng dụng khách cụ thể, được thực hiện thông qua mã ứng dụng khách không bắt buộc và một số dữ liệu ứng dụng khách không bắt buộc (tương ứng là Tag::APPLICATION_ID
và Tag::APPLICATION_DATA
). Kho khoá coi các giá trị này là các blob mờ, chỉ đảm bảo rằng cùng một blob được hiển thị trong quá trình tạo/nhập khoá được hiển thị cho mọi mục đích sử dụng và giống hệt nhau từng byte. KeyMint không trả về dữ liệu liên kết ứng dụng. Phương thức gọi phải biết giá trị này để sử dụng khoá.
Ứng dụng không thấy tính năng này.
Hết hạn
Kho khoá hỗ trợ việc hạn chế việc sử dụng khoá theo ngày. Bạn có thể liên kết thời điểm bắt đầu và thời điểm hết hạn của khoá với một khoá và Kho khoá sẽ từ chối thực hiện các thao tác với khoá nếu ngày/giờ hiện tại nằm ngoài phạm vi hợp lệ. Phạm vi hợp lệ của khoá được chỉ định bằng các thẻ Tag::ACTIVE_DATETIME
, Tag::ORIGINATION_EXPIRE_DATETIME
và Tag::USAGE_EXPIRE_DATETIME
. Sự khác biệt giữa "nguồn gốc" và "mục đích sử dụng" dựa trên việc khoá đang được dùng để "tạo" văn bản đã mã hoá/chữ ký/v.v. mới hay để "sử dụng" văn bản đã mã hoá/chữ ký/v.v. hiện có. Xin lưu ý rằng sự khác biệt này không được hiển thị cho ứng dụng.
Bạn không bắt buộc phải sử dụng thẻ Tag::ACTIVE_DATETIME
, Tag::ORIGINATION_EXPIRE_DATETIME
và Tag::USAGE_EXPIRE_DATETIME
. Nếu không có thẻ, giả định rằng khoá cần xác minh luôn có thể được dùng để giải mã/xác minh thư.
Vì thời gian đồng hồ thực tế do thế giới không an toàn cung cấp, nên các thẻ liên quan đến thời gian hết hạn nằm trong danh sách do phần mềm thực thi.
Liên kết gốc tin cậy
Kho khoá yêu cầu các khoá phải được liên kết với một gốc tin cậy, đây là một chuỗi bit được cung cấp cho phần cứng bảo mật KeyMint trong quá trình khởi động, tốt nhất là do trình tải khởi động cung cấp. Chuỗi bit này được liên kết bằng phương thức mã hoá với mọi khoá do KeyMint quản lý.
Gốc tin cậy bao gồm hàm băm của khoá công khai dùng để xác minh chữ ký trên hình ảnh khởi động và trạng thái khoá của thiết bị. Nếu khoá công khai được thay đổi để cho phép sử dụng một hình ảnh hệ thống khác hoặc nếu trạng thái khoá được thay đổi, thì không có khoá nào được KeyMint bảo vệ do hệ thống trước đó tạo ra có thể sử dụng được, trừ phi gốc tin cậy trước đó được khôi phục và hệ thống được ký bằng khoá đó được khởi động. Mục tiêu là tăng giá trị của các biện pháp kiểm soát quyền truy cập vào khoá do phần mềm thực thi bằng cách ngăn hệ điều hành do kẻ tấn công cài đặt sử dụng khoá KeyMint.
Tạo lại giá trị khởi tạo cho trình tạo số ngẫu nhiên
Vì phần cứng bảo mật tạo số ngẫu nhiên cho tài liệu khoá và vectơ khởi chạy (IV) và vì trình tạo số ngẫu nhiên phần cứng không phải lúc nào cũng đáng tin cậy, nên HAL KeyMint cung cấp một giao diện để cho phép Kho khoá cung cấp thêm entropy, được trộn vào số ngẫu nhiên được tạo.
Sử dụng trình tạo số ngẫu nhiên phần cứng làm nguồn hạt chính. Dữ liệu hạt được cung cấp thông qua API bên ngoài không thể là nguồn ngẫu nhiên duy nhất dùng để tạo số. Hơn nữa, thao tác trộn được sử dụng cần đảm bảo rằng kết quả ngẫu nhiên là không thể dự đoán nếu bất kỳ nguồn hạt nào cũng không thể dự đoán.