Tính năng

Trang này chứa thông tin về các tính năng mã hóa của Keystore trong Android 6.0 trở lên.

Mật mã nguyên thủy

Keystore cung cấp các loại hoạt động sau:

  • Tạo khóa
  • Nhập và xuất các khóa bất đối xứng (không gói khóa)
  • Nhập khóa đối xứng thô (không gói khóa)
  • Mã hóa và giải mã bất đối xứng với các chế độ đệm thích hợp
  • Ký và xác minh không đối xứng với chế độ tóm tắt và phần đệm thích hợp
  • Mã hóa và giải mã đối xứng ở các chế độ thích hợp, bao gồm chế độ AEAD
  • Tạo và xác minh mã xác thực tin nhắn đối xứng

Các thành phần giao thức, chẳng hạn như mục đích, chế độ và phần đệm, cũng như các ràng buộc kiểm soát truy cập , được chỉ định khi khóa được tạo hoặc nhập và được liên kết vĩnh viễn với khóa, đảm bảo khóa không thể được sử dụng theo bất kỳ cách nào khác.

Ngoài danh sách trên, còn có một dịch vụ nữa mà quá trình triển khai Keymaster cung cấp nhưng không được hiển thị dưới dạng API: Tạo số ngẫu nhiên. Điều này được sử dụng nội bộ để tạo khóa, Vectơ khởi tạo (IV), đệm ngẫu nhiên và các thành phần khác của giao thức bảo mật yêu cầu tính ngẫu nhiên.

Nguyên thủy cần thiết

Tất cả việc triển khai Keymaster đều cung cấp:

  • RSA
    • Hỗ trợ khóa 2048, 3072 và 4096-bit
    • Hỗ trợ số mũ công khai F4 (2^16+1)
    • Các chế độ đệm để ký RSA:
      • RSASSA-PSS ( PaddingMode::RSA_PSS )
      • RSASSA-PKCS1-v1_5 ( PaddingMode::RSA_PKCS1_1_5_SIGN )
    • Các chế độ thông báo để ký RSA:
      • SHA-256
    • Các chế độ đệm để mã hóa/giải mã RSA:
      • Không được đệm
      • RSAES-OAEP ( PaddingMode::RSA_OAEP )
      • RSAES-PKCS1-v1_5 ( PaddingMode::RSA_PKCS1_1_5_ENCRYPT )
  • ECDSA
    • Hỗ trợ khóa 224, 256, 384 và 521-bit, sử dụng các đường cong NIST P-224, P-256, P-384 và P-521 tương ứng
    • Chế độ phân loại cho ECDSA:
      • Không có thông báo nào (không được dùng nữa, sẽ bị xóa trong tương lai)
      • SHA-256
  • AES
    • Hỗ trợ khóa 128 và 256 bit
    • CBC , TLB, ECB và GCM. Việc triển khai GCM không cho phép sử dụng các thẻ nhỏ hơn 96 bit hoặc độ dài nonce khác 96 bit.
    • Chế độ đệm PaddingMode::NONEPaddingMode::PKCS7 được hỗ trợ cho chế độ CBC và ECB. Không có phần đệm, mã hóa chế độ CBC hoặc ECB sẽ không thành công nếu đầu vào không phải là bội số của kích thước khối.
  • HMAC SHA-256 , với bất kỳ kích thước khóa nào lên tới ít nhất 32 byte.

SHA1 và các thành viên khác trong dòng SHA2 (SHA-224, SHA384 và SHA512) được khuyến khích sử dụng để triển khai Keymaster. Keystore cung cấp chúng trong phần mềm nếu việc triển khai Keymaster phần cứng không cung cấp chúng.

Một số nguyên thủy cũng được khuyến nghị để có khả năng tương tác với các hệ thống khác:

  • Kích thước khóa nhỏ hơn cho RSA
  • Số mũ công khai tùy ý cho RSA

Kiểm soát truy cập khóa

Các khóa dựa trên phần cứng không bao giờ có thể trích xuất được khỏi thiết bị sẽ không cung cấp nhiều bảo mật nếu kẻ tấn công có thể sử dụng chúng theo ý muốn (mặc dù chúng an toàn hơn các khóa có thể bị lấy cắp). Vì vậy, điều quan trọng là Keystore phải thực thi các biện pháp kiểm soát truy cập.

Kiểm soát truy cập được định nghĩa là "danh sách ủy quyền" của các cặp thẻ/giá trị. Thẻ ủy quyền là số nguyên 32 bit và các giá trị có nhiều loại khác nhau. 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 tài liệu dành cho thẻ đó . Khi một khóa được tạo, người gọi sẽ chỉ định danh sách ủy quyền. Việc triển khai Keymaster bên dưới Keystore sẽ sửa đổi danh sách để chỉ định một số thông tin bổ sung, chẳng hạn như liệu khóa có bảo vệ khôi phục hay không và trả về danh sách ủy quyền "cuối cùng", được mã hóa vào blob khóa được trả về. Mọi nỗ lực sử dụng khóa cho bất kỳ hoạt động mã hóa nào đều không thành công nếu danh sách ủy quyền cuối cùng bị sửa đổi.

Đối với Keymaster 2 trở về trước, tập hợp các thẻ có thể được xác định trong bảng liệt kê keymaster_authorization_tag_t và được cố định vĩnh viễn (mặc dù có thể mở rộng). Tên có tiền tố là KM_TAG . Bốn bit trên cùng của ID thẻ được sử dụng để chỉ ra loại.

Keymaster 3 đã đổi tiền tố KM_TAG thành Tag:: .

Các loại có thể bao gồm:

ENUM : Giá trị của nhiều thẻ được xác định trong bảng liệt kê. Ví dụ: các giá trị có thể có của TAG::PURPOSE được xác định trong enum keymaster_purpose_t .

ENUM_REP : Tương tự như ENUM , ngoại trừ thẻ có thể được lặp lại trong danh sách ủy quyền. Sự lặp lại biểu thị nhiều giá trị được ủy quyền. Ví dụ: khóa mã hóa có thể có KeyPurpose::ENCRYPTKeyPurpose::DECRYPT .

UINT : số nguyên không dấu 32 bit. Ví dụ: TAG::KEY_SIZE

UINT_REP : Tương tự như UINT , ngoại trừ thẻ có thể được lặp lại trong danh sách ủy quyền. Sự lặp lại biểu thị nhiều giá trị được ủy quyền.

ULONG : số nguyên không dấu 64-bit. Ví dụ: TAG::RSA_PUBLIC_EXPONENT

ULONG_REP : Tương tự như ULONG , ngoại trừ thẻ có thể được lặp lại trong danh sách ủy quyền. Sự lặp lại biểu thị nhiều giá trị được ủy quyền.

DATE : Giá trị ngày/giờ, được biểu thị bằng mili giây kể từ ngày 1 tháng 1 năm 1970. Ví dụ: TAG::PRIVKEY_EXPIRE_DATETIME

BOOL : Đúng hoặc sai. Thẻ loại BOOL được coi là "false" nếu thẻ không tồn tại và "true" nếu có. Ví dụ: TAG::ROLLBACK_RESISTANT

BIGNUM : Số nguyên có độ dài tùy ý, được biểu thị dưới dạng mảng byte theo thứ tự big-endian. Ví dụ: TAG::RSA_PUBLIC_EXPONENT

BYTES : Một chuỗi byte. Ví dụ: TAG::ROOT_OF_TRUST

Thực thi phần cứng và phần mềm

Không phải tất cả việc triển khai phần cứng an toàn đều có các tính năng giống nhau. Để hỗ trợ nhiều phương pháp tiếp cận khác nhau, Keymaster phân biệt giữa thực thi kiểm soát truy cập thế giới an toàn và không bảo mật hoặc thực thi phần cứng và phần mềm tương ứng.

Tất cả các triển khai:

  • Thực thi đối sánh chính xác (không thực thi) tất cả các ủy quyền. Danh sách ủy quyền trong các đốm màu khóa khớp chính xác với các ủy quyền được trả về trong quá trình tạo khóa, bao gồm cả việc đặt hàng. Bất kỳ sự không phù hợp nào đều gây ra chẩn đoán lỗi.
  • Khai báo các ủy quyền có giá trị ngữ nghĩa được thực thi.

Cơ chế API để khai báo các ủy quyền được thực thi bằng phần cứng nằm trong cấu trúc keymaster_key_characteristics_t . Nó chia danh sách ủy quyền thành hai danh sách phụ, hw_enforcedsw_enforced . Phần cứng bảo mật chịu trách nhiệm đặt các giá trị thích hợp vào từng phần, dựa trên những gì nó có thể thực thi.

Ngoài ra, Keystore triển khai thực thi tất cả các ủy quyền dựa trên phần mềm, cho dù chúng có được thực thi bởi phần cứng bảo mật hay không.

Ví dụ: hãy xem xét triển khai dựa trên TrustZone không hỗ trợ hết hạn khóa. Một khóa có ngày hết hạn vẫn có thể được tạo. Danh sách ủy quyền của khóa đó sẽ bao gồm thẻ TAG::ORIGINATION_EXPIRE_DATETIME cùng với ngày hết hạn. Yêu cầu tới Keystore về các đặc điểm chính sẽ tìm thấy thẻ này trong danh sách sw_enforced và phần cứng bảo mật sẽ không thực thi yêu cầu hết hạn. Tuy nhiên, những nỗ lực sử dụng khóa sau khi hết hạn sẽ bị Keystore từ chối.

Sau đó, nếu thiết bị được nâng cấp bằng phần cứng bảo mật hỗ trợ hết hạn thì yêu cầu về các đặc điểm chính sẽ tìm thấy TAG::ORIGINATION_EXPIRE_DATETIME trong danh sách hw_enforced và các nỗ lực sử dụng khóa sau khi hết hạn sẽ không thành công ngay cả khi kho khóa bị phá hủy hoặc bỏ qua bằng cách nào đó .

Để biết thêm thông tin về cách xác định xem khóa có được hỗ trợ bằng phần cứng hay không, hãy xem Chứng thực khóa .

Ủy quyền xây dựng thông điệp mật mã

Các thẻ sau được sử dụng để xác định đặc điểm mật mã của các hoạt động sử dụng khóa liên quan: TAG::ALGORITHM , TAG::KEY_SIZE , TAG::BLOCK_MODE , TAG::PADDING , TAG::CALLER_NONCETAG::DIGEST

TAG::PADDING , TAG::DIGESTPaddingMode::BLOCK_MODE có thể lặp lại, nghĩa là nhiều giá trị có thể được liên kết với một khóa duy nhất và giá trị được sử dụng được chỉ định tại thời điểm hoạt động.

Mục đích

Khóa có một nhóm mục đích liên quan, được biểu thị dưới dạng một hoặc nhiều mục ủy quyền có thẻ TAG::PURPOSE , xác định cách sử dụng chúng. Mục đích là:

  • KeyPurpose::ENCRYPT
  • KeyPurpose::DECRYPT
  • KeyPurpose::SIGN
  • KeyPurpose::VERIFY

Bất kỳ khóa nào cũng có thể có bất kỳ tập hợp con nào cho các mục đích này. Lưu ý rằng một số kết hợp tạo ra vấn đề bảo mật. Ví dụ: khóa RSA có thể được sử dụng để mã hóa và ký tên cho phép kẻ tấn công có thể thuyết phục hệ thống giải mã dữ liệu tùy ý để tạo chữ ký.

Nhập khẩu và xuất khẩu

Keymaster chỉ hỗ trợ xuất khóa chung ở định dạng X.509 và nhập:

  • Cặp khóa công khai và riêng tư ở định dạng PKCS#8 được mã hóa DER, không cần mã hóa dựa trên mật khẩu
  • Khóa đối xứng dưới dạng byte thô

Để đảm bảo rằng các khóa đã nhập có thể được phân biệt với các khóa được tạo an toàn, TAG::ORIGIN được đưa vào danh sách ủy quyền khóa thích hợp. Ví dụ: nếu khóa được tạo trong phần cứng bảo mật, TAG::ORIGIN với giá trị KeyOrigin::GENERATED sẽ được tìm thấy trong danh sách hw_enforced gồm các đặc điểm khóa, trong khi khóa đượ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

Việc triển khai Keymaster an toàn không triển khai 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 thực hiện việc này. Để biết giao diện mà các ứng dụng này triển khai, hãy xem trang Gatekeeper .

Yêu cầu xác thực người dùng được chỉ định thông qua hai bộ thẻ. Bộ đầu tiên cho biết người dùng nào có thể sử dụng khóa:

  • TAG::ALL_USERS cho biết tất cả người dùng đều có thể sử dụng khóa này. Nếu có thì TAG::USER_IDTAG::USER_SECURE_ID không có.
  • TAG::USER_ID có giá trị số chỉ định ID của người dùng được ủy quyền. Lưu ý rằng đây là ID người dùng Android (dành cho nhiều người dùng), không phải UID ứng dụng và nó chỉ được thực thi bởi phần mềm không bảo mật. Nếu có thì TAG::ALL_USERS không có.
  • TAG::USER_SECURE_ID có giá trị số 64-bit chỉ định ID người dùng bảo mật được cung cấp trong mã thông báo xác thực an toàn để mở khóa việc sử dụng khóa. Nếu lặp lại, khóa có thể được sử dụng nếu bất kỳ giá trị nào được cung cấp trong mã thông báo xác thực an toàn.

Bộ 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. Nếu không có thẻ nào trong số này nhưng có TAG::USER_SECURE_ID thì cần phải xác thực cho mỗi lần sử dụng khóa.

  • NO_AUTHENTICATION_REQUIRED cho biết không cần xác thực người dùng, mặc dù khóa vẫn chỉ có thể được sử dụng bởi các ứng dụng đang chạy với tư cách là (những) người dùng được chỉ định bởi TAG::USER_ID .
  • TAG::AUTH_TIMEOUT là một giá trị số chỉ định, tính bằng giây, mức độ mới của xác thực người dùng để cho phép sử dụng khóa. Điều này chỉ áp dụng cho các hoạt động khóa riêng tư/bí mật. Hoạt động khóa công khai không yêu cầu xác thực. Thời gian chờ không vượt qua các lần khởi động lại; sau khi khởi động lại, tất cả các khóa đều "không bao giờ được xác thực". Thời gian chờ có thể được đặt thành giá trị lớn để cho biết rằng cần phải xác thực một lần cho mỗi lần khởi động (2^32 giây là ~136 năm; có lẽ các thiết bị Android được khởi động lại thường xuyên hơn thế).

Ràng buộc khách hàng

Liên kết ứng dụng khách, việc liên kết khóa với một ứng dụng ứng dụng khách cụ thể, được thực hiện thông qua ID ứng dụng khách tùy chọn và một số dữ liệu ứng dụng khách tùy chọn ( TAG::APPLICATION_IDTAG::APPLICATION_DATA tương ứng). Kho khóa xử lý các giá trị này dưới dạng các đốm màu mờ đục, chỉ đảm bảo rằng các đốm màu giống nhau được trình bày trong quá trình tạo/nhập khóa được hiển thị cho mỗi lần sử dụng và giống hệt nhau theo từng byte. Dữ liệu liên kết máy khách không được Keymaster trả về. Người gọi phải biết điều đó để sử dụng chìa khóa.

Tính năng này không được hiển thị với các ứng dụng.

Hết hạn

Keystore hỗ trợ hạn chế sử dụng khóa theo ngày. Việc bắt đầu hiệu lực của khóa và hết hạn khóa có thể được liên kết với một khóa và Keymaster từ chối thực hiện các thao tác khóa 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 khóa được chỉ định bằng các thẻ TAG::ACTIVE_DATETIME , TAG::ORIGINATION_EXPIRE_DATETIMETAG::USAGE_EXPIRE_DATETIME . Sự khác biệt giữa "gốc" và "cách sử dụng" dựa trên việc khóa đang được sử dụng để "khởi tạo" một bản mã/chữ ký/v.v. mới hay để "sử dụng" một bản mã/chữ ký/v.v. hiện có. Lưu ý rằng sự khác biệt này không được thể hiện trong các ứng dụng.

Các TAG::ACTIVE_DATETIME , TAG::ORIGINATION_EXPIRE_DATETIMETAG::USAGE_EXPIRE_DATETIME là tùy chọn. Nếu không có thẻ, giả định rằng khóa được đề cập luôn có thể được sử dụng để giải mã/xác minh tin nhắn.

Bởi vì thời gian trên đồng hồ treo tường được cung cấp bởi thế giới không an toàn nên ít có khả năng các thẻ liên quan đến hết hạn sẽ nằm trong danh sách được thực thi bằng phần cứng. Việc thực thi phần cứng hết hạn sẽ yêu cầu thế giới an toàn bằng cách nào đó có được thời gian và dữ liệu đáng tin cậy, ví dụ như thông qua giao thức phản hồi thử thách với máy chủ thời gian từ xa đáng tin cậy.

Ràng buộc niềm tin

Kho khóa yêu cầu các khóa phải được liên kết với gốc tin cậy, là chuỗi bit được cung cấp cho phần cứng bảo mật Keymaster trong quá trình khởi động, tốt nhất là bởi bộ tải khởi động. Chuỗi bit này được liên kết bằng mật mã với mọi khóa do Keymaster quản lý.

Root của sự tin cậy bao gồm khóa chung được sử dụng để xác minh chữ ký trên boot image và trạng thái khóa của thiết bị. Nếu khóa chung được thay đổi để cho phép sử dụng hình ảnh hệ thống khác hoặc nếu trạng thái khóa bị thay đổi thì không có khóa nào được bảo vệ bởi Keymaster do hệ thống trước tạo ra có thể sử dụng được, trừ khi gốc tin cậy trước đó được khôi phục và hệ thống được ký bởi khóa đó đã được khởi động. Mục tiêu là tăng giá trị của các điều khiển truy cập khóa được thực thi bằng phần mềm bằng cách khiến hệ điều hành do kẻ tấn công cài đặt không thể sử dụng khóa Keymaster.

Phím độc lập

Một số phần cứng bảo mật của Keymaster có thể chọn lưu trữ nội bộ tài liệu khóa và trả lại các thẻ điều khiển thay vì tài liệu khóa được mã hóa. Hoặc có thể có những trường hợp khác trong đó khóa không thể được sử dụng cho đến khi có sẵn một số thành phần hệ thống thế giới không an toàn hoặc không an toàn khác. Keymaster HAL cho phép người gọi yêu cầu một khóa ở trạng thái "độc lập" thông qua thẻ TAG::STANDALONE , nghĩa là không yêu cầu tài nguyên nào ngoài blob và hệ thống Keymaster đang chạy. Các thẻ liên kết với một khóa có thể được kiểm tra để xem liệu khóa đó có độc lập hay không. Hiện tại chỉ có hai giá trị được xác định:

  • KeyBlobUsageRequirements::STANDALONE
  • KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM

Tính năng này không được hiển thị với các ứng dụng.

vận tốc

Khi được tạo, tốc độ sử dụng tối đa có thể được chỉ định bằng TAG::MIN_SECONDS_BETWEEN_OPS . Việc triển khai TrustZone từ chối thực hiện các hoạt động mã hóa bằng khóa đó nếu một thao tác được thực hiện ít hơn TAG::MIN_SECONDS_BETWEEN_OPS giây trước đó.

Cách tiếp cận đơn giản để triển khai giới hạn vận tốc là một bảng gồm các ID khóa và dấu thời gian sử dụng lần cuối. Bảng này có thể sẽ có kích thước giới hạn nhưng chứa được ít nhất 16 mục. Trong trường hợp bảng đầy và không có mục nào có thể được cập nhật hoặc loại bỏ, việc triển khai phần cứng an toàn sẽ "không an toàn", ưu tiên từ chối tất cả các thao tác phím có giới hạn tốc độ cho đến khi một trong các mục hết hạn. Có thể chấp nhận được tất cả các mục sẽ hết hạn khi khởi động lại.

Các khóa cũng có thể được giới hạn ở n lần sử dụng cho mỗi lần khởi động với TAG::MAX_USES_PER_BOOT . Điều này cũng yêu cầu một bảng theo dõi, chứa ít nhất bốn chìa khóa và cũng không an toàn. Lưu ý rằng các ứng dụng sẽ không thể tạo các khóa giới hạn cho mỗi lần khởi động. Tính năng này không được hiển thị thông qua Keystore và được dành riêng cho các hoạt động của hệ thống.

Tính năng này không được hiển thị với các ứng dụng.

Tạo lại bộ tạo số ngẫu nhiên

Do phần cứng bảo mật tạo ra các số ngẫu nhiên cho vật liệu chính và vectơ khởi tạo (IV) và do trình tạo số ngẫu nhiên của phần cứng có thể không phải lúc nào cũng đáng tin cậy hoàn toàn nên Keymaster HAL cung cấp giao diện để cho phép khách hàng cung cấp entropy bổ sung sẽ được trộn vào mã ngẫu nhiên. số được tạo ra.

Sử dụng trình tạo số ngẫu nhiên phần cứng làm nguồn giống chính. Dữ liệu gốc đượ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 được sử dụng để tạo số. Hơn nữa, thao tác trộn được sử dụng cần phải đảm bảo rằng đầu ra ngẫu nhiên là không thể đoán trước được nếu bất kỳ nguồn giống nào là không thể đoán trước được.

Tính năng này không được hiển thị trong các ứng dụng nhưng được sử dụng bởi khung công tác này, thường xuyên cung cấp entropy bổ sung, được truy xuất từ ​​phiên bản Java SecureRandom, tới phần cứng bảo mật.