Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.

Chứng thực Key và ID

Kho khóa cung cấp một nơi an toàn hơn để tạo, lưu trữ và sử dụng khóa mật mã theo cách được kiểm soát. Khi lưu trữ khóa được hỗ trợ bởi phần cứng có sẵn và được sử dụng, tài liệu khóa sẽ an toàn hơn trước việc khai thác khỏi thiết bị và Keymaster thực thi các hạn chế khó phá hủy.

Tuy nhiên, điều này chỉ đúng nếu các khóa kho khóa được biết là nằm trong bộ nhớ được hỗ trợ bởi phần cứng. Trong Keymaster 1, không có cách nào để các ứng dụng hoặc máy chủ từ xa xác minh một cách đáng tin cậy xem có đúng như vậy không. Daemon keystore đã tải keymaster HAL có sẵn và tin rằng bất cứ điều gì HAL đã nói về phần cứng hỗ trợ key.

Để khắc phục điều này, Keymaster đã giới thiệuchứng thực khóa trong Android 7.0 (Keymaster 2) và chứng thực ID trong Android 8.0 (Keymaster 3).

Chứng thực khóa nhằm mục đích cung cấp một cách để xác định một cách mạnh mẽ xem một cặp khóa bất đối xứng có được hỗ trợ bằng phần cứng hay không, các thuộc tính của khóa là gì và những ràng buộc nào được áp dụng cho việc sử dụng nó.

Chứng thực ID cho phép thiết bị cung cấp bằng chứng về số nhận dạng phần cứng, chẳng hạn như số sê-ri hoặc IMEI.

Chứng thực chính

Để hỗ trợ chứng thực khóa, Android 7.1 đã giới thiệu một bộ thẻ, loại và phương pháp cho HAL.

Thẻ

  • Tag::ATTESTATION_CHALLENGE
  • Tag::INCLUDE_UNIQUE_ID
  • Tag::RESET_SINCE_ID_ROTATION

Thể loại

Keymaster 2 trở xuống

typedef struct {
    keymaster_blob_t* entries;
    size_t entry_count;
} keymaster_cert_chain_t;

Phương thức AttestKey

Keymaster 3

    attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams)
        generates(ErrorCode error, vec<vec<uint8_t>> certChain);

Keymaster 2 trở xuống

keymaster_error_t (*attest_key)(const struct keymaster2_device* dev,
        const keymaster_key_blob_t* key_to_attest,
        const keymaster_key_param_set_t* attest_params,
        keymaster_cert_chain_t* cert_chain);
  • dev là cấu trúc thiết bị keymaster.
  • keyToAttest là key blob được trả về từ generateKey mà chứng thực sẽ được tạo.
  • attestParams là danh sách các tham số cần thiết để chứng thực. Điều này bao gồm Tag::ATTESTATION_CHALLENGE và có thể là Tag::RESET_SINCE_ID_ROTATION , cũng như Tag::APPLICATION_IDTag::APPLICATION_DATA . Hai phần sau là cần thiết để giải mã key blob nếu chúng được chỉ định trong quá trình tạo khóa.
  • certChain là tham số đầu ra, trả về một mảng chứng chỉ. Mục 0 là chứng chỉ chứng thực, nghĩa là nó xác nhận khóa từ keyToAttest và chứa phần mở rộng chứng thực.

Phương thức attestKey được coi là một hoạt động khóa công khai trên khóa đã được chứng thực, bởi vì nó có thể được gọi bất kỳ lúc nào và không cần phải đáp ứng các ràng buộc ủy quyền. Ví dụ: nếu khóa được chứng thực cần xác thực người dùng để sử dụng, thì chứng thực có thể được tạo mà không cần xác thực người dùng.

Chứng chỉ chứng thực

Chứng chỉ chứng thực là chứng chỉ X.509 tiêu chuẩn, với phần mở rộng chứng thực tùy chọn chứa mô tả về khóa được chứng thực. Chứng chỉ được ký bằng khóa chứng thực do nhà máy cấp phép sử dụng cùng một thuật toán với khóa đang được chứng thực (RSA cho RSA, EC cho EC).

Chứng chỉ chứng thực chứa các trường trong bảng bên dưới và không được chứa bất kỳ trường bổ sung nào. Một số trường chỉ định một giá trị trường cố định. Các bài kiểm tra CTS xác nhận rằng nội dung chứng chỉ chính xác như được định nghĩa.

Chứng chỉ SEQUENCE

Tên trường (xem RFC 5280 ) Giá trị
tbsCertificate TBSCertificate SEQUENCE
chữ ký AlgorithmIdentifier của thuật toán được sử dụng để ký khóa:
ECDSA cho khóa EC, RSA cho khóa RSA.
signatureValue BIT STRING, chữ ký được tính trên tbsCertificate được mã hóa ASN.1 DER.

TBSCertificate SEQUENCE

Tên trường (xem RFC 5280 ) Giá trị
version INTEGER 2 (nghĩa là chứng chỉ v3)
serialNumber INTEGER 1 (giá trị cố định: giống nhau trên tất cả các chứng chỉ)
signature AlgorithmIdentifier của thuật toán dùng để ký khóa: ECDSA cho khóa EC, RSA cho khóa RSA.
issuer Giống như trường chủ đề của khóa chứng thực hàng loạt.
validity SEQUENCE của hai ngày, chứa các giá trị của Thẻ :: ACTIVE_DATETIMEThẻ :: USAGE_EXPIRE_DATETIME . Các giá trị đó tính bằng mili giây kể từ ngày 1 tháng 1 năm 1970. Xem RFC 5280 để biết cách trình bày ngày tháng chính xác trong chứng chỉ.
Nếu Tag::ACTIVE_DATETIME không có, hãy sử dụng giá trị của Tag::CREATION_DATETIME . Nếu Tag::USAGE_EXPIRE_DATETIME không có, hãy sử dụng ngày hết hạn của chứng chỉ khóa chứng thực hàng loạt.
subject CN = "Khóa kho khóa Android" (giá trị cố định: giống nhau trên tất cả các chứng chỉ)
subjectPublicKeyInfo SubjectPublicKeyInfo chứa khóa công khai đã được chứng thực.
extensions/Key Usage digitalSignature: đặt nếu khóa có mục đích KeyPurpose::SIGN hoặc KeyPurpose::VERIFY . Tất cả các bit khác chưa được đặt.
extensions/CRL Distribution Points Giá trị TBD
extensions/"attestation" OID là 1.3.6.1.4.1.11129.2.1.17; nội dung được xác định trong phần Mở rộng Chứng thực bên dưới. Như với tất cả các phần mở rộng chứng chỉ X.509, nội dung được biểu thị dưới dạng OCTET_STRING chứa mã hóa DER của chứng thực SEQUENCE.

Phần mở rộng chứng thực

Tiện ích mở rộng attestation chứa mô tả đầy đủ về các ủy quyền của quản trị viên khóa được liên kết với khóa, trong cấu trúc tương ứng trực tiếp với danh sách ủy quyền được sử dụng trong Android và quản trị viên khóa HAL. Mỗi thẻ trong danh sách ủy quyền được đại diện bởi một mục nhập ASN.1 SEQUENCE , được gắn thẻ rõ ràng bằng số thẻ quản trị viên khóa, nhưng với bộ mô tả loại (bốn bit thứ tự cao) bị che đi.

Ví dụ: trong Keymaster 3, Tag::PURPOSE được định nghĩa trong styles.hal là ENUM_REP | 1 . Đối với phần mở rộng chứng thực, giá trị ENUM_REP bị xóa, để lại thẻ 1 . (Đối với Keymaster 2 trở xuống, KM_TAG_PURPOSE được xác định trong keymaster_defs.h.)

Các giá trị được dịch một cách dễ hiểu sang các loại ASN.1, theo bảng này:

Keymaster loại Loại ASN.1
ENUM INTEGER
ENUM_REP BỘ INTEGER
UINT INTEGER
UINT_REP BỘ INTEGER
ULONG INTEGER
ULONG_REP BỘ INTEGER
DATE INTEGER (mili giây kể từ ngày 1 tháng 1 năm 1970 00:00:00 GMT)
BOOL NULL (trong keymaster, thẻ hiện tại có nghĩa là đúng, không có nghĩa là sai.
Ngữ nghĩa tương tự áp dụng cho mã hóa ASN.1)
BIGNUM Hiện không được sử dụng, vì vậy không có ánh xạ nào được xác định
BYTES OCTET_STRING

Lược đồ

Nội dung phần mở rộng chứng thực được mô tả bằng lược đồ ASN.1 sau.

KeyDescription ::= SEQUENCE {
  attestationVersion         INTEGER, # KM2 value is 1. KM3 value is 2. KM4 value is 3.
  attestationSecurityLevel   SecurityLevel,
  keymasterVersion           INTEGER,
  keymasterSecurityLevel     SecurityLevel,
  attestationChallenge       OCTET_STRING,
  uniqueId                   OCTET_STRING,
  softwareEnforced           AuthorizationList,
  teeEnforced                AuthorizationList,
}

SecurityLevel ::= ENUMERATED {
  Software                   (0),
  TrustedEnvironment         (1),
  StrongBox                  (2),
}

AuthorizationList ::= SEQUENCE {
  purpose                     [1] EXPLICIT SET OF INTEGER OPTIONAL,
  algorithm                   [2] EXPLICIT INTEGER OPTIONAL,
  keySize                     [3] EXPLICIT INTEGER OPTIONAL.
  digest                      [5] EXPLICIT SET OF INTEGER OPTIONAL,
  padding                     [6] EXPLICIT SET OF INTEGER OPTIONAL,
  ecCurve                     [10] EXPLICIT INTEGER OPTIONAL,
  rsaPublicExponent           [200] EXPLICIT INTEGER OPTIONAL,
  rollbackResistance          [303] EXPLICIT NULL OPTIONAL, # KM4
  activeDateTime              [400] EXPLICIT INTEGER OPTIONAL
  originationExpireDateTime   [401] EXPLICIT INTEGER OPTIONAL
  usageExpireDateTime         [402] EXPLICIT INTEGER OPTIONAL
  noAuthRequired              [503] EXPLICIT NULL OPTIONAL,
  userAuthType                [504] EXPLICIT INTEGER OPTIONAL,
  authTimeout                 [505] EXPLICIT INTEGER OPTIONAL,
  allowWhileOnBody            [506] EXPLICIT NULL OPTIONAL,
  trustedUserPresenceRequired [507] EXPLICIT NULL OPTIONAL, # KM4
  trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, # KM4
  unlockedDeviceRequired      [509] EXPLICIT NULL OPTIONAL, # KM4
  allApplications             [600] EXPLICIT NULL OPTIONAL,
  applicationId               [601] EXPLICIT OCTET_STRING OPTIONAL,
  creationDateTime            [701] EXPLICIT INTEGER OPTIONAL,
  origin                      [702] EXPLICIT INTEGER OPTIONAL,
  rollbackResistant           [703] EXPLICIT NULL OPTIONAL, # KM2 and KM3 only.
  rootOfTrust                 [704] EXPLICIT RootOfTrust OPTIONAL,
  osVersion                   [705] EXPLICIT INTEGER OPTIONAL,
  osPatchLevel                [706] EXPLICIT INTEGER OPTIONAL,
  attestationApplicationId    [709] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdBrand          [710] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdDevice         [711] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdProduct        [712] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdSerial         [713] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdImei           [714] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdMeid           [715] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdManufacturer   [716] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  attestationIdModel          [717] EXPLICIT OCTET_STRING OPTIONAL, # KM3
  vendorPatchLevel            [718] EXPLICIT INTEGER OPTIONAL, # KM4
  bootPatchLevel              [719] EXPLICIT INTEGER OPTIONAL, # KM4
}

RootOfTrust ::= SEQUENCE {
  verifiedBootKey            OCTET_STRING,
  deviceLocked               BOOLEAN,
  verifiedBootState          VerifiedBootState,
  verifiedBootHash           OCTET_STRING, # KM4
}

VerifiedBootState ::= ENUMERATED {
  Verified                   (0),
  SelfSigned                 (1),
  Unverified                 (2),
  Failed                     (3),
}

Các trường KeyDescription

Các trường keymasterVersionattestationChallenge được xác định theo vị trí, thay vì theo thẻ, vì vậy các thẻ trong biểu mẫu được mã hóa chỉ xác định loại trường. Các trường còn lại được gắn thẻ ngầm như được chỉ định trong lược đồ.

Tên trường Thể loại Giá trị
attestationVersion INTEGER Phiên bản của lược đồ chứng thực: 1, 2 hoặc 3.
attestationSecurity SecurityLevel Mức độ bảo mật của chứng thực này. Có thể nhận được chứng thực phần mềm của các phím được hỗ trợ bằng phần cứng. Những chứng thực như vậy không thể đáng tin cậy nếu hệ thống Android bị xâm phạm.
keymasterVersion INTEGER Phiên bản của thiết bị keymaster: 0, 1, 2, 3 hoặc 4.
keymasterSecurity SecurityLevel Mức độ bảo mật của việc triển khai keymaster.
attestationChallenge OCTET_STRING Giá trị của Tag::ATTESTATION_CHALLENGE , được chỉ định cho yêu cầu chứng thực.
uniqueId OCTET_STRING ID duy nhất tùy chọn, hiển thị nếu khóa có Tag::INCLUDE_UNIQUE_ID
softwareEnforced AuthorizationList Các ủy quyền tùy chọn của quản trị viên khóa không được TEE thực thi, nếu có.
teeEnforced AuthorizationList Các ủy quyền tùy chọn của Keymaster được TEE thực thi, nếu có.

Các trường AuthorizationList

Các trường AuthorizationList đều là tùy chọn và được xác định bằng giá trị thẻ keymaster, với các bit loại được che đi. Gắn thẻ rõ ràng được sử dụng để các trường cũng chứa thẻ cho biết loại ASN.1 của chúng, để phân tích cú pháp dễ dàng hơn.

Để biết chi tiết về các giá trị của từng trường, hãy xem các types.hal cho Keymaster 3 và keymaster_defs.h cho Keymaster 2 trở xuống. Tên thẻ Keymaster đã được chuyển đổi thành tên trường bằng cách bỏ qua tiền tố KM_TAG và thay đổi phần còn lại thành chữ hoa camel, vì vậy Tag::KEY_SIZE trở thành keySize .

Các trường RootOfTrust

Các trường RootOfTrust được xác định theo vị trí.

Tên trường Thể loại Giá trị
verifiedBootKey OCTET_STRING Băm bảo mật của khóa được sử dụng để xác minh hình ảnh hệ thống. SHA-256 được khuyến nghị.
deviceLocked BOOLEAN Đúng nếu bộ nạp khởi động bị khóa, có nghĩa là chỉ những hình ảnh đã ký mới có thể được hiển thị và quá trình kiểm tra khởi động đã xác minh được thực hiện.
verifiedBootState VerifiedBootState Trạng thái khởi động đã xác minh.
verifiedBootHash OCTET_STRING Thông báo về tất cả dữ liệu được bảo vệ bởi Khởi động đã xác minh. Đối với các thiết bị sử dụng triển khai Khởi động đã xác minh của Android, Khởi động đã xác minh, giá trị này chứa thông báo về cấu trúc VBMeta hoặc cấu trúc siêu dữ liệu Khởi động đã xác minh. Để tìm hiểu thêm về cách tính giá trị này, hãy xem Thông báo VBMeta

Giá trị VerifiedBootState

Các giá trị của verifiedBootState có các ý nghĩa sau:

Giá trị Nghĩa
Verified Cho biết một chuỗi tin cậy đầy đủ mở rộng từ bộ nạp khởi động đến các phân vùng đã được xác minh, bao gồm bộ nạp khởi động, phân vùng khởi động và tất cả các phân vùng đã được xác minh.
Ở trạng thái này, giá trị verifiedBootKey là băm của chứng chỉ nhúng, nghĩa là chứng chỉ không thể thay đổi được ghi vào ROM.
SelfSigned Cho biết phân vùng khởi động đã được xác minh bằng chứng chỉ nhúng và chữ ký hợp lệ. Bộ nạp khởi động hiển thị cảnh báo và dấu vân tay của khóa công khai trước khi cho phép tiếp tục quá trình khởi động.
Ở trạng thái này, giá trị verifiedBootKey là mã băm của chứng chỉ tự ký.
Unverified Cho biết một thiết bị có thể được sửa đổi tự do. Tính toàn vẹn của thiết bị được để cho người dùng xác minh ngoài băng tần. Bộ nạp khởi động hiển thị cảnh báo cho người dùng trước khi cho phép tiếp tục quá trình khởi động.
Ở trạng thái này, giá trị verifiedBootKey trống.
Failed Cho biết thiết bị đã không xác minh được. Không có chứng chỉ chứng thực nào thực sự chứa giá trị này, bởi vì ở trạng thái này, bộ nạp khởi động tạm dừng. Nó được bao gồm ở đây để hoàn thiện.

Giá trị SecurityLevel

Các giá trị của securityLevel có các ý nghĩa sau:

Giá trị Nghĩa
Software Mã tạo hoặc quản lý phần tử có liên quan (chứng thực hoặc khóa) được triển khai trong hệ thống Android và có thể bị thay đổi nếu hệ thống đó bị xâm phạm.
TrustedEnvironment Mã tạo hoặc quản lý phần tử có liên quan (chứng thực hoặc khóa) được triển khai trong Môi trường thực thi đáng tin cậy (TEE). Nó có thể bị thay đổi nếu TEE bị xâm phạm, nhưng TEE có khả năng chống lại sự xâm nhập từ xa cao và khả năng chống lại sự xâm phạm do tấn công phần cứng trực tiếp ở mức trung bình.
StrongBox Mã tạo hoặc quản lý phần tử liên quan (chứng thực hoặc khóa) được triển khai trong mô-đun bảo mật phần cứng chuyên dụng. Nó có thể bị thay đổi nếu mô-đun bảo mật phần cứng bị xâm phạm, nhưng nó có khả năng chống lại sự xâm nhập từ xa và khả năng chống lại sự xâm phạm do tấn công phần cứng trực tiếp rất cao.

ID duy nhất

ID duy nhất là một giá trị 128 bit xác định thiết bị, nhưng chỉ trong một khoảng thời gian giới hạn. Giá trị được tính bằng:

HMAC_SHA256(T || C || R, HBK)

Ở đâu:

  • T là "giá trị bộ đếm thời gian", được tính bằng cách chia giá trị của Tag::CREATION_DATETIME cho 2592000000, giảm bất kỳ phần còn lại nào. T thay đổi 30 ngày một lần (2592000000 = 30 * 24 * 60 * 60 * 1000).
  • C là giá trị của Tag::APPLICATION_ID
  • R là 1 nếu Tag::RESET_SINCE_ID_ROTATION có trong tham số attest_params cho lệnh gọi attest_key hoặc 0 nếu không có thẻ.
  • HBK là một bí mật liên quan đến phần cứng duy nhất được biết đến với Môi trường thực thi đáng tin cậy và không bao giờ được tiết lộ bởi nó. Bí mật chứa ít nhất 128 bit entropy và là duy nhất cho từng thiết bị (tính duy nhất theo xác suất được chấp nhận với 128 bit entropy). HBK phải được lấy từ tài liệu khóa hợp nhất thông qua HMAC hoặc AES_CMAC.

Cắt ngắn đầu ra HMAC_SHA256 thành 128 bit.

Khóa chứng thực và chứng chỉ

Hai khóa, một RSA và một ECDSA, và chuỗi chứng chỉ tương ứng, được cung cấp an toàn vào thiết bị.

Chứng thực ID

Android 8.0 bao gồm hỗ trợ tùy chọn cho chứng thực ID cho các thiết bị có Keymaster 3. Chứng thực ID cho phép thiết bị cung cấp bằng chứng về các số nhận dạng phần cứng, chẳng hạn như số sê-ri hoặc IMEI. Mặc dù là một tính năng tùy chọn, nhưng tất cả các triển khai Keymaster 3 đều được khuyến khích cung cấp hỗ trợ cho nó vì khả năng chứng minh danh tính của thiết bị cho phép các trường hợp sử dụng như cấu hình điều khiển từ xa không chạm thực sự trở nên an toàn hơn (vì phía điều khiển từ xa có thể chắc chắn điều đó đang nói chuyện với đúng thiết bị, không phải thiết bị giả mạo danh tính của nó).

Chứng thực ID hoạt động bằng cách tạo bản sao của số nhận dạng phần cứng của thiết bị mà chỉ Môi trường thực thi đáng tin cậy (TEE) mới có thể truy cập trước khi thiết bị rời khỏi nhà máy. Người dùng có thể mở khóa bộ nạp khởi động của thiết bị và thay đổi phần mềm hệ thống cũng như số nhận dạng được các khung Android báo cáo. Không thể thao tác các bản sao của số nhận dạng do TEE nắm giữ theo cách này, đảm bảo rằng chứng thực ID thiết bị sẽ chỉ chứng thực các số nhận dạng phần cứng ban đầu của thiết bị, do đó ngăn chặn các nỗ lực giả mạo.

Bề mặt API chính để chứng thực ID được xây dựng dựa trên cơ chế chứng thực khóa hiện có được giới thiệu với Keymaster 2. Khi yêu cầu chứng chỉ chứng thực cho khóa do keymaster nắm giữ, người gọi có thể yêu cầu đưa số nhận dạng phần cứng của thiết bị vào siêu dữ liệu của chứng chỉ chứng thực. Nếu khóa được giữ trong TEE, chứng chỉ sẽ liên kết trở lại gốc tin cậy đã biết. Người nhận chứng chỉ như vậy có thể xác minh rằng chứng chỉ và nội dung của nó, bao gồm cả số nhận dạng phần cứng, đã được viết bởi TEE. Khi được yêu cầu bao gồm các số nhận dạng phần cứng trong chứng chỉ chứng thực, TEE chỉ kiểm tra các số nhận dạng được lưu trữ trong bộ lưu trữ của nó, như được phổ biến tại nhà máy.

Thuộc tính lưu trữ

Bộ nhớ lưu giữ số nhận dạng của thiết bị cần có các thuộc tính sau:

  • Các giá trị thu được từ số nhận dạng ban đầu của thiết bị được sao chép vào bộ nhớ trước khi thiết bị xuất xưởng.
  • Phương thức destroyAttestationIds() có thể hủy vĩnh viễn bản sao dữ liệu có nguồn gốc từ mã định danh này. Phá hủy vĩnh viễn nghĩa là dữ liệu bị xóa hoàn toàn nên không khôi phục cài đặt gốc hay bất kỳ quy trình nào khác được thực hiện trên thiết bị. Điều này đặc biệt quan trọng đối với các thiết bị mà người dùng đã mở khóa bộ nạp khởi động và thay đổi phần mềm hệ thống cũng như sửa đổi số nhận dạng do các khung Android trả về.
  • Các cơ sở RMA phải có khả năng tạo các bản sao mới của dữ liệu lấy từ mã định danh phần cứng. Bằng cách này, một thiết bị đi qua RMA có thể thực hiện lại quá trình xác thực ID. Cơ chế được sử dụng bởi các cơ sở RMA phải được bảo vệ để người dùng không thể tự gọi nó, vì điều đó sẽ cho phép họ có được chứng thực về các ID giả mạo.
  • Không có mã nào ngoài ứng dụng đáng tin cậy Keymaster trong TEE có thể đọc dữ liệu lấy từ mã nhận dạng được lưu trong bộ nhớ.
  • Lưu trữ có dấu hiệu giả mạo: Nếu nội dung của lưu trữ đã được sửa đổi, TEE sẽ xử lý nội dung đó giống như thể các bản sao của nội dung đã bị hủy và từ chối mọi nỗ lực chứng thực ID. Điều này được thực hiện bằng cách ký hoặc MACing bộ nhớ như được mô tả bên dưới .
  • Bộ nhớ không chứa các số nhận dạng ban đầu. Vì việc chứng thực ID liên quan đến một thách thức, người gọi luôn cung cấp các số nhận dạng để được chứng thực. TEE chỉ cần xác minh rằng những giá trị này khớp với các giá trị mà chúng có ban đầu. Việc lưu trữ các hàm băm an toàn của các giá trị gốc thay vì các giá trị sẽ cho phép xác minh này.

Xây dựng

Để tạo một triển khai có các thuộc tính được liệt kê ở trên, hãy lưu trữ các giá trị bắt nguồn từ ID trong cấu trúc sau S. Không lưu trữ các bản sao khác của giá trị ID, ngoại trừ các vị trí bình thường trong hệ thống mà chủ sở hữu thiết bị có thể sửa đổi bằng cách root:

S = D || HMAC(HBK, D)

ở đâu:

  • D = HMAC(HBK, ID 1 ) || HMAC(HBK, ID 2 ) || ... || HMAC(HBK, ID n )
  • HMAC là cấu trúc HMAC với hàm băm an toàn thích hợp (đề nghị SHA-256)
  • HBK là một khóa ràng buộc phần cứng không được sử dụng cho bất kỳ mục đích nào khác
  • ID 1 ...ID n là các giá trị ID gốc; sự liên kết của một giá trị cụ thể với một chỉ mục cụ thể phụ thuộc vào việc triển khai, vì các thiết bị khác nhau sẽ có số lượng định danh khác nhau
  • || đại diện cho nối

Bởi vì đầu ra HMAC có kích thước cố định, không có tiêu đề hoặc cấu trúc khác được yêu cầu để có thể tìm thấy các băm ID riêng lẻ hoặc HMAC của D. Ngoài việc kiểm tra các giá trị đã cung cấp để thực hiện chứng thực, việc triển khai cần xác thực S bằng cách trích xuất D từ S , tính toán HMAC (HBK, D) và so sánh nó với giá trị trong S để xác minh rằng không có ID cá nhân nào bị sửa đổi / bị hỏng. Ngoài ra, việc triển khai phải sử dụng so sánh thời gian không đổi cho tất cả các phần tử ID riêng lẻ và xác thực S. Thời gian so sánh phải không đổi bất kể số lượng ID được cung cấp và sự khớp chính xác của bất kỳ phần nào của thử nghiệm.

Số nhận dạng phần cứng

Chứng thực ID hỗ trợ các số nhận dạng phần cứng sau:

  1. Tên thương hiệu, do Build.BRAND trả lại trong Android
  2. Tên thiết bị, do Build.DEVICE trả lại trong Android
  3. Tên sản phẩm, được trả lại bởi Build.PRODUCT trong Android
  4. Tên nhà sản xuất, do Build.MANUFACTURER trả lại trong Android
  5. Tên kiểu máy, được trả về bởi Build.MODEL trong Android
  6. Số seri
  7. IMEI của tất cả các đài
  8. MEID của tất cả các đài

Để hỗ trợ chứng thực ID thiết bị, một thiết bị sẽ chứng thực những số nhận dạng này. Tất cả các thiết bị chạy Android đều có sáu đầu tiên và chúng cần thiết để tính năng này hoạt động. Nếu thiết bị có bất kỳ bộ đàm di động tích hợp nào, thiết bị đó cũng phải hỗ trợ chứng thực IMEI và / hoặc MEID của bộ đàm.

Chứng thực ID được yêu cầu bằng cách thực hiện chứng thực khóa và bao gồm các số nhận dạng thiết bị để chứng thực trong yêu cầu. Các số nhận dạng được gắn thẻ là:

  • ATTESTATION_ID_BRAND
  • ATTESTATION_ID_DEVICE
  • ATTESTATION_ID_PRODUCT
  • ATTESTATION_ID_MANUFACTURER
  • ATTESTATION_ID_MODEL
  • ATTESTATION_ID_SERIAL
  • ATTESTATION_ID_IMEI
  • ATTESTATION_ID_MEID

Số nhận dạng để chứng thực là một chuỗi byte được mã hóa UTF-8. Định dạng này cũng áp dụng cho các định danh số. Mỗi từ định danh để chứng thực được biểu thị dưới dạng một chuỗi được mã hóa UTF-8.

Nếu thiết bị không hỗ trợ chứng thực ID (hoặc destroyAttestationIds() trước đó đã được gọi và thiết bị không còn có thể chứng thực các ID của nó nữa), thì bất kỳ yêu cầu chứng thực khóa nào bao gồm một hoặc nhiều thẻ này đều không thành công với ErrorCode::CANNOT_ATTEST_IDS .

Nếu thiết bị hỗ trợ chứng thực ID và một hoặc nhiều thẻ ở trên đã được đưa vào yêu cầu chứng thực khóa, thì TEE sẽ xác minh số nhận dạng được cung cấp cùng với mỗi thẻ khớp với bản sao của số nhận dạng phần cứng. Nếu một hoặc nhiều số nhận dạng không khớp, toàn bộ chứng thực không thành công với Mã lỗi ErrorCode::CANNOT_ATTEST_IDS . Nó hợp lệ cho cùng một thẻ được cung cấp nhiều lần. Điều này có thể hữu ích, chẳng hạn như khi kiểm tra IMEI: Một thiết bị có thể có nhiều radio với nhiều IMEI. Yêu cầu chứng thực là hợp lệ nếu giá trị được cung cấp với mỗi ATTESTATION_ID_IMEI khớp với một trong các bộ đàm của thiết bị. Điều tương tự cũng áp dụng cho tất cả các thẻ khác.

Nếu chứng thực thành công, các ID đã chứng thực sẽ được thêm vào phần mở rộng chứng thực (OID 1.3.6.1.4.1.11129.2.1.17) của chứng chỉ chứng thực đã cấp, sử dụng lược đồ từ trên . Các thay đổi từ lược đồ chứng thực Keymaster 2 được in đậm , kèm theo các nhận xét.

API Java

Phần này chỉ là thông tin. Người triển khai Keymaster không triển khai cũng như không sử dụng API Java. Điều này được cung cấp để giúp người triển khai hiểu cách ứng dụng sử dụng tính năng này. Các thành phần hệ thống có thể sử dụng nó theo cách khác nhau, đó là lý do tại sao phần quan trọng này không được coi là quy chuẩn.