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á. Chứng chỉ 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ởi một chuỗi khoá có nguồn từ một gốc đáng tin cậy.
- Các 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)
Hãy lưu ý rằng Kho khoá (Keystore) và KeyMint không xử lý các phép toán trên 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 ràng buộc kiểm soát quyền truy cập đều được chỉ định khi khoá được tạo hoặc nhập. Những phần tử này đượ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 và không thể trích xuất khỏi thiết bị sẽ không đảm bảo nhiều tính bảo mật nếu kẻ tấn công có thể tuỳ ý sử dụng các khoá đó (mặc dù chúng vẫn an toàn hơn so với các khoá có thể bị đánh cắp). 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 định nghĩa là "danh sách uỷ quyền" gồm 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ị. Khả năng lặp lại của một thẻ được quy định trong giao diện HAL của 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 thẻ sẽ liên kết với một TagType
để cho biết loại giá trị liên quan (ví dụ: số nguyên hoặc byte), cũng như việc thẻ đó có thể 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 Kho khoá và KeyMint sửa đổi để bổ sung các quy tắc ràng buộc, đồ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 tập hợp dữ liệu khoá (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 đó, bất kỳ nỗ lực nào nhằm sửa đổi danh sách uỷ quyền này (kể cả việc sắp xếp thứ tự) cũng sẽ tạo ra 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 kiểu 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
ở cấp độ 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 thể hiện 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
, còn các đặc điểm của SecurityLevel::SOFTWARE
hoặc SecurityLevel::KEYSTORE
thì 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 ngày và giờ khi một khoá có thể được sử dụng 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 để định nghĩa các đặc điểm mật mã của các hoạt động 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ị được sử dụng sẽ được chỉ định tại thời điểm thực hiện phép toán.
Mục đích
Các khoá có một tập hợp các mục đích liên kết, được thể hiện dưới dạng một hoặc nhiều mục nhập uỷ quyền có thẻ Tag::PURPOSE
. Thẻ này định nghĩa cách sử dụng các mục nhập đó. Các mục đích được xác định trong KeyPurpose.aidl
.
Lưu ý rằng một số cách kết hợp các giá trị mục đích sẽ tạo ra vấn đề về bảo mật. Ví dụ: một khoá RSA có thể dùng để vừa mã hoá vừa 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 rằng các khoá đã nhập có thể được phân biệt với các khoá được tạo một cách an toàn, Tag::ORIGIN
sẽ đượ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 về xác thực người dùng được chỉ định thông qua hai tập hợp thẻ. Tập hợp đầu tiên cho biết phương pháp xác thực nào cho phép sử dụng khoá:
Tag::USER_SECURE_ID
có một giá trị số 64 bit xác định ID người dùng bảo mật được cung cấp trong mã xác thực bảo mật để mở khoá việc sử dụng khoá. Nếu được 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ột 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ỉ giới hạn cho ứng dụng sở hữu khoá (và mọi ứng dụng mà khoá đó cấp quyền truy cập).Tag::AUTH_TIMEOUT
là một giá trị số (tính bằng giây) chỉ định thời gian mà thông tin xác thực người dùng phải còn hiệu lực để cấp quyền việc sử dụng khoá. Thời gian chờ không kéo dài quá các 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 việc xác thực là bắt buộc cho mỗi lần khởi động (2^32 giây là khoảng 136 năm; 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ị ở trạng thái 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ị được khoá. Điều này nhằm đảm bảo rằng, trong hầu hết các trường hợp, các khoá đó không thể bị sử dụng ngay cả khi Kho khoá bị xâm phạm lúc thiết đang khoá.
Để làm được điều này, Kho khoá sẽ "mã hoá siêu cấp" tất cả các khoá UNLOCKED_DEVICE_REQUIRED
trước khi lưu trữ vào cơ sở dữ liệu của kho khoá. Đồng thời, khi có thể, kho khoá sẽ bảo vệ các khoá mã hoá siêu cấp (siêu khoá) 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ổ sung trên 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 siêu khoá liên kết với UNLOCKED_DEVICE_REQUIRED
:
- Siêu khoá đố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. - SIêu khoá 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á).
Khi người dùng được tạo, Kho khoá tạo các siêu khoá này và lưu trữ vào cơ sở dữ liệu của Kho, được mã hoá bằng mật khẩu tổng hợp của người dùng. Phương thức này cho phép khôi phục siêu khoá 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 siêu khoá 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á, Kho khoá sẽ xoá bản sao của các phần bí mật của các siêu khoá này trong bộ nhớ đệm của Kho (nếu có thể). Cụ thể, khi thiết bị ở chế độ khoá, Kho khoá sẽ chọn và áp dụng một trong ba cấp độ bảo vệ cho siêu khoá 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ẽ xoá các phần bí mật của siêu khoá được lưu vào bộ nhớ đệm của kho. Điều này làm cho các siêu khoá chỉ có thể khôi phục được thông qua bản sao được 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ỉ bật dữ liệu sinh trắc học loại 3 ("mạnh") cùng với mã PIN, hình mở khoá hoặc mật khẩu, thì Kho khoá sẽ sắp xếp để siêu khoá có thể được khôi phục bằng bất kỳ dữ liệu sinh trắc học loại 3 nào mà người dùng đã đăng ký (thường là vân tay), thay cho mã PIN, hình mở khoá hoặc mật khẩu tương đương. Để làm được điều này, Kho khoá sẽ tạo một khoá AES‑256‑GCM mới, dùng khoá đó để mã hoá các phần bí mật của các siêu khoá, nhập khoá AES‑256‑GCM này vào KeyMint dưới dạng khoá ràng buộc sinh trắc học. Khoá này yêu cầu xác thực sinh trắc học phải thành công trong vòng 15 giây gần nhất. Sau đó, Kho khoá sẽ xoá các bản sao văn bản thuần tuý của tất cả các khoá này.
- Nếu người dùng đã bật tính năng sinh trắc học loại 1 ("thuận tiện"), sinh trắc học loại 2 ("yếu") hoặc tác nhân tin cậy mở khoá đang hoạt động, thì Kho khoá sẽ giữ các siêu khoá đã lưu trong bộ nhớ đệm ở dạng văn bản thuần tuý. Trong trường hợp này, bảo mật mã hoá cho các khoá
UNLOCKED_DEVICE_REQUIRED
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 kích hoạt các phương thức mở khoá đó. Các phương thức mở khoá phổ biến nhất thuộc những loại này bao gồm 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 đã được ghép nối.
Khi thiết bị ở trạng thái mở khoá, Kho khoá sẽ khôi phục siêu khoá UnlockedDeviceRequired của người dùng nếu có thể. Đối với phương thức mở khoá bằng mã PIN, hình mở khoá hoặc mật khẩu tương đương, Kho khoá sẽ giải mã bản sao của các khoá này đã được lưu trữ trong cơ sở dữ liệu. Trong trường hợp khác, Kho khoá sẽ kiểm tra xem liệu kho có lưu một bản sao của các khoá này được mã hoá bằng khoá ràng buộc sinh trắc học hay không, và nếu có thì sẽ cố gắng giải mã. Quá trình này chỉ thành công nếu người dùng đã xác thực thành công bằng sinh trắc học loại 3 trong vòng 15 giây gần nhất, một yêu cầu được thực thi bởi KeyMint (không phải Kho khoá).
Ràng buộc ứng dụng khách
Ràng buộc ứng dụng khách, tức là sự liên kết của một khoá với một ứng dụng khách cụ thể, được thực hiện thông qua một ID ứ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á xử lý các giá trị này như các khối dữ liệu không rõ ràng, chỉ đảm bảo rằng các khối dữ liệu giống hệt nhau được cung cấp trong quá trình tạo/nhập khoá cũng được cung cấp mỗi lần sử dụng và giống hệt nhau từng byte. KeyMint không trả về dữ liệu ràng buộc ứng dụng khách. Phương thức gọi phải biết dữ liệu này để sử dụng khoá.
Tính năng này không hiển thị trên các ứng dụng.
Thời hạn
Kho khoá hỗ trợ giới hạn việc sử dụng khoá theo ngày. Ngày bắt đầu có hiệu lực và ngày hết hạn của khoá có thể được liên kết với một khoá và Kho khoá từ chối thực hiện các hoạt động khoá nếu ngày/giờ hiện tại nằm ngoài phạm vi hợp lệ. Phạm vi hiệu lực của khoá được chỉ định bằng các thẻ Tag::ACTIVE_DATETIME
, Tag::ORIGINATION_EXPIRE_DATETIME
và Tag::USAGE_EXPIRE_DATETIME
. Sự phân biệt giữa "khởi tạo" và "sử dụng" dựa trên việc khoá được dùng để "khởi tạo" văn bản đã mã hoá/chữ ký mới, v.v. hay để "sử dụng" văn bản đã mã hoá/chữ ký mới, v.v. hiện có. Bạn nên lưu ý rằng sự khác biệt này không được hiển thị trên ứ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ó các thẻ này, có thể cho rằng khoá được đề cập luôn có thể được sử dụng để giải mã hoặc xác minh thông điệp.
Vì thời gian thực được cung cấp bởi môi trường không bảo mật, các thẻ liên quan đến thời hạn nằm trong danh sách do phần mềm thực thi.
Liên kết với 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, đó 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 ràng buộc 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 bị 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á bị thay đổi, thì không có khoá nào được KeyMint bảo vệ do hệ thống trước đó tạo ra là có thể sử dụng được, trừ phi gốc tin cậy trước đó được khôi phục và một 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 chế độ kiểm soát quyền truy cập 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 các khoá KeyMint.
Nạp giá trị khởi tạo cho trình tạo số ngẫu nhiên
Bởi vì phần cứng bảo mật tạo ra các số ngẫu nhiên cho tài liệu khoá và vectơ khởi tạo (IV), và bởi 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 các số ngẫu nhiên được tạo ra.
Sử dụng một trình tạo số ngẫu nhiên phần cứng làm nguồn chính. Dữ liệu giá trị khởi tạo được cung cấp qua API bên ngoài không thể là nguồn duy nhất của tính ngẫu nhiên 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 đầu ra ngẫu nhiên là không thể đoán trước ngay cả khi chỉ một nguồn dữ liệu giá trị khởi tạo là không thể đoán trước.