キーストアは、暗号鍵の作成、保存、使用を適切に制御できる安全な場所を提供します。ハードウェア格納型の鍵ストレージが利用可能で実際に使用されている場合、鍵マテリアルがデバイスから抽出される危険はより少なくなり、Keymaster が適用する制限を打ち破るのはより難しくなります。
ただし、それはキーストア鍵がハードウェア格納型ストレージ内にあることが認識される場合に限られます。Keymaster 1 では、そのような状態をアプリまたはリモート サーバーが確実に確認する方法はありませんでした。キーストア デーモンは、利用可能な Keymaster HAL を読み込んで、鍵がハードウェアに格納されているかどうかに関して HAL の記述を受け入れることしかできませんでした。
この状況を改善するため、Keymaster は Android 7.0(Keymaster 2)で鍵構成証明、Android 8.0(Keymaster 3)で ID 構成証明を導入しました。
鍵構成証明の目的は、非対称鍵ペアがハードウェア格納型鍵としてサポートされているかどうか、鍵の特性は何か、鍵の使用に適用される制約は何かを厳密に判断する方法を提供することです。
ID 構成証明を使用すると、デバイスはシリアル番号や IMEI などのハードウェア識別子の証明を提供できます。
キー構成証明
キー構成証明をサポートするため、Android 7.0 では、タグ、型、メソッドのセットが HAL に導入されました。
タグ
Tag::ATTESTATION_CHALLENGE
Tag::INCLUDE_UNIQUE_ID
Tag::RESET_SINCE_ID_ROTATION
型
Keymaster 2 以下
typedef struct { keymaster_blob_t* entries; size_t entry_count; } keymaster_cert_chain_t;
AttestKey
メソッド
Keymaster 3
attestKey(vec<uint8_t> keyToAttest, vec<KeyParameter> attestParams) generates(ErrorCode error, vec<vec<uint8_t>> certChain);
Keymaster 2 以下
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
は、Keymaster のデバイス構造です。keyToAttest
は、generateKey
から返される鍵 blob です。これに対して構成証明が作成されます。attestParams
は、構成証明に必要なパラメータのリストです。パラメータにはTag::APPLICATION_ID
とTag::APPLICATION_DATA
に加えてTag::ATTESTATION_CHALLENGE
があり、Tag::RESET_SINCE_ID_ROTATION
が含まれることもあります。最初の 2 つのパラメータは、鍵の生成時に指定された鍵 blob を復号するために必要です。certChain
は、証明書の配列を返す出力パラメータです。エントリ 0 は構成証明書です。構成証明書とは、構成証明拡張を含む、keyToAttest
の鍵の証明書です。
attestKey
メソッドは、いつでも呼び出すことができ、承認の制約を満たす必要がないため、証明済みの鍵に対する公開鍵オペレーションと見なされます。たとえば、証明済みの鍵の使用にユーザー認証が必要な場合、ユーザー認証なしで構成証明を生成できます。
構成証明書
構成証明書は標準の X.509 証明書であり、証明済みの鍵の説明を含む構成証明拡張がオプションとしてあります。証明書は、認定済みの構成証明鍵で署名されます。この鍵は、証明対象の鍵とは異なるアルゴリズムを使用する場合があります。
構成証明書には、下記の表のフィールドが含まれます。フィールドを追加することはできません。一部のフィールドには、固定フィールド値が指定されています。CTS テストでは、証明書の内容が正確に定義どおりであるかどうかが検証されます。
Certificate SEQUENCE
フィールド名(RFC 5280 を参照) | 値 |
---|---|
tbsCertificate | TBSCertificate SEQUENCE |
signatureAlgorithm | 鍵の署名に使用されるアルゴリズムの AlgorithmIdentifier: EC 鍵の場合は ECDSA、RSA 鍵の場合は RSA。 |
signatureValue | BNT STRING。ASN.1 DER でエンコードされた tbsCertificate で算出された署名。 |
TBSCertificate SEQUENCE
フィールド名(RFC 5280 を参照) | 値 |
---|---|
version |
INTEGER 2(v3 証明書を意味します) |
serialNumber |
INTEGER 1(固定値: すべての証明書で同一) |
signature |
鍵の署名に使用されるアルゴリズムの AlgorithmIdentifier: EC 鍵の場合は ECDSA、RSA 鍵の場合は RSA。 |
issuer |
バッチ構成証明鍵の subject フィールドと同じです。 |
validity |
Tag::ACTIVE_DATETIME と Tag::USAGE_EXPIRE_DATETIME の値を含む 2 つの日付の SEQUENCE。
これらの値は、1970 年 1 月 1 日からのミリ秒数です。
証明書の正確な日付表現については、RFC 5280 をご覧ください。Tag::ACTIVE_DATETIME が存在しない場合は、Tag::CREATION_DATETIME の値を使用します。Tag::USAGE_EXPIRE_DATETIME が存在しない場合は、バッチ構成証明の鍵証明書の有効期限の日付を使用します。 |
subject |
CN = "Android キーストア鍵"(固定値: すべての証明書で同一) |
subjectPublicKeyInfo |
証明済みの公開鍵を含む SubjectPublicKeyInfo。 |
extensions/Key Usage |
digitalSignature: 鍵に目的 KeyPurpose::SIGN または KeyPurpose::VERIFY がある場合に設定されます。他のビットはすべて未設定です。 |
extensions/CRL Distribution Points |
値は未定 |
extensions/"attestation" |
OID は 1.3.6.1.4.1.11129.2.1.17 です。内容は下記の構成証明拡張のセクションで定義されています。すべての X.509 証明書拡張と同様に、内容は構成証明 SEQUENCE の DER エンコードを含む OCTET_STRING として表現されます。 |
構成証明拡張
attestation
拡張の OID は 1.3.6.1.4.1.11129.2.1.17
です。証明対象の鍵ペアや、鍵生成時のデバイスの状態に関する情報が含まれています。
AIDL インターフェース仕様で定義されている Keymaster / KeyMint タグの型は、以下のような ASN.1 の型に変換されます。
Keymaster / KeyMint の型 | ASN.1 の型 | 備考 |
---|---|---|
ENUM |
INTEGER |
|
ENUM_REP |
SET of INTEGER |
|
UINT |
INTEGER |
|
UINT_REP |
SET of INTEGER |
|
ULONG |
INTEGER |
|
ULONG_REP |
SET of INTEGER |
|
DATE |
INTEGER |
1970 年 1 月 1 日 00:00:00 GMT からのミリ秒数。 |
BOOL |
NULL |
タグが存在する場合は true、存在しない場合は false。 |
BIGNUM |
この型のタグはないため、マッピングは定義されていません。 | |
BYTES |
OCTET_STRING |
スキーマ
構成証明拡張の内容は、次の ASN.1 スキーマによって記述されます。
バージョン 300
KeyDescription ::= SEQUENCE { attestationVersion 300, attestationSecurityLevel SecurityLevel, keyMintVersion INTEGER, keyMintSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced 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, mgfDigest [203] EXPLICIT SET OF INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, usageCountLimit [405] 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, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, attestationIdSecondImei [723] EXPLICIT OCTET_STRING OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
バージョン 200
KeyDescription ::= SEQUENCE { attestationVersion 200, attestationSecurityLevel SecurityLevel, keyMintVersion INTEGER, keyMintSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced 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, mgfDigest [203] EXPLICIT SET OF INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, usageCountLimit [405] 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, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
バージョン 100
KeyDescription ::= SEQUENCE { attestationVersion 100, attestationSecurityLevel SecurityLevel, keyMintVersion INTEGER, keyMintSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced 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, mgfDigest [203] EXPLICIT SET OF INTEGER OPTIONAL, rollbackResistance [303] EXPLICIT NULL OPTIONAL, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, activeDateTime [400] EXPLICIT INTEGER OPTIONAL, originationExpireDateTime [401] EXPLICIT INTEGER OPTIONAL, usageExpireDateTime [402] EXPLICIT INTEGER OPTIONAL, usageCountLimit [405] 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, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
バージョン 4
KeyDescription ::= SEQUENCE { attestationVersion 4, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced 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, earlyBootOnly [305] EXPLICIT NULL OPTIONAL, 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, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, deviceUniqueAttestation [720] EXPLICIT NULL OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
バージョン 3
KeyDescription ::= SEQUENCE { attestationVersion 3, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced 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, 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, trustedConfirmationRequired [508] EXPLICIT NULL OPTIONAL, unlockedDeviceRequired [509] EXPLICIT NULL OPTIONAL, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, vendorPatchLevel [718] EXPLICIT INTEGER OPTIONAL, bootPatchLevel [719] EXPLICIT INTEGER OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, verifiedBootHash OCTET_STRING, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
バージョン 2
KeyDescription ::= SEQUENCE { attestationVersion 2, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), } 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, 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, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, attestationApplicationId [709] EXPLICIT OCTET_STRING OPTIONAL, attestationIdBrand [710] EXPLICIT OCTET_STRING OPTIONAL, attestationIdDevice [711] EXPLICIT OCTET_STRING OPTIONAL, attestationIdProduct [712] EXPLICIT OCTET_STRING OPTIONAL, attestationIdSerial [713] EXPLICIT OCTET_STRING OPTIONAL, attestationIdImei [714] EXPLICIT OCTET_STRING OPTIONAL, attestationIdMeid [715] EXPLICIT OCTET_STRING OPTIONAL, attestationIdManufacturer [716] EXPLICIT OCTET_STRING OPTIONAL, attestationIdModel [717] EXPLICIT OCTET_STRING OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
バージョン 1
KeyDescription ::= SEQUENCE { attestationVersion 1, attestationSecurityLevel SecurityLevel, keymasterVersion INTEGER, keymasterSecurityLevel SecurityLevel, attestationChallenge OCTET_STRING, uniqueId OCTET_STRING, softwareEnforced AuthorizationList, hardwareEnforced AuthorizationList, } SecurityLevel ::= ENUMERATED { Software (0), TrustedEnvironment (1), } 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, 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, allApplications [600] EXPLICIT NULL OPTIONAL, creationDateTime [701] EXPLICIT INTEGER OPTIONAL, origin [702] EXPLICIT INTEGER OPTIONAL, rollbackResistant [703] EXPLICIT NULL OPTIONAL, rootOfTrust [704] EXPLICIT RootOfTrust OPTIONAL, osVersion [705] EXPLICIT INTEGER OPTIONAL, osPatchLevel [706] EXPLICIT INTEGER OPTIONAL, } RootOfTrust ::= SEQUENCE { verifiedBootKey OCTET_STRING, deviceLocked BOOLEAN, verifiedBootState VerifiedBootState, } VerifiedBootState ::= ENUMERATED { Verified (0), SelfSigned (1), Unverified (2), Failed (3), }
KeyDescription フィールド
-
attestationVersion
-
ASN.1 スキーマのバージョン。
値 Keymaster / KeyMint のバージョン 1 Keymaster バージョン 2.0 2 Keymaster バージョン 3.0 3 Keymaster バージョン 4.0 4 Keymaster バージョン 4.1 100 KeyMint バージョン 1.0 200 KeyMint バージョン 2.0 300 KeyMint バージョン 3.0 -
attestationSecurityLevel
-
証明対象の鍵が保存されている場所のセキュリティ レベル。
-
keymasterVersion
/keyMintVersion
-
Keymaster / KeyMint の Hardware Abstraction Layer(HAL)実装のバージョン。
値 Keymaster / KeyMint のバージョン 2 Keymaster バージョン 2.0 3 Keymaster バージョン 3.0 4 Keymaster バージョン 4.0 41 Keymaster バージョン 4.1 100 KeyMint バージョン 1.0 200 KeyMint バージョン 2.0 300 KeyMint バージョン 3.0 -
keymasterSecurityLevel
/keyMintSecurityLevel
- Keymaster / KeyMint 実装のセキュリティ レベル。
-
attestationChallenge
- 鍵生成時に提供されるチャレンジ。
-
uniqueId
- 鍵生成時にシステムアプリがリクエストできる、プライバシーに配慮する必要のあるデバイス識別子。一意の ID がリクエストされていない場合、このフィールドは空白になります。詳しくは一意の ID のセクションをご覧ください。
-
softwareEnforced
- Android システムによって適用される Keymaster / KeyMint の承認リスト。この情報はプラットフォームのコードによって収集または生成され、デバイスのシステム パーティションに保存されます。デバイスに搭載されているオペレーティング システムが Android プラットフォーム セキュリティ モデルに準拠したもの(つまりデバイスのブートローダーがロックされ、
verifiedBootState
がVerified
)である限り、信頼できます。 -
hardwareEnforced
- デバイスの高信頼実行環境(TEE)または StrongBox によって適用される Keymaster / KeyMint の承認リスト。この情報は安全なハードウェアのコードによって収集または生成されます。プラットフォームによって制御されることはありません。たとえばブートローダーから、またはプラットフォームを信頼する必要のない安全な通信チャネルを通じて、情報が取得されます。
SecurityLevel の値
SecurityLevel
の値は、キーストア関連の要素(鍵ペアや証明書など)が攻撃に対してどの程度の耐性を持っているのかを示します。
値 | 意味 |
---|---|
Software |
デバイスの Android システムが Android プラットフォーム セキュリティ モデルに準拠している(つまりデバイスのブートローダーがロックされ、verifiedBootState が Verified である)限り安全です。 |
TrustedEnvironment |
高信頼実行環境(TEE)が侵害されない限り安全です。TTE の分離要件は、Android 互換性定義ドキュメントのセクション 9.11 [C-1-1] から [C-1-4] で定義されています。TEE の耐性は、リモート侵害に対しては高く、直接のハードウェア攻撃による侵害に対しては中程度です。 |
StrongBox |
StrongBox が侵害されない限り安全です。StrongBox は、ハードウェア セキュリティ モジュールに類似したセキュア エレメントに実装されます。StrongBox の実装要件は、Android 互換性定義ドキュメントのセクション 9.11.2 で定義されています。StrongBox は、リモート侵害に対しても、直接のハードウェア攻撃による侵害(物理的な改ざんやサイドチャネル攻撃など)に対しても高い耐性を持っています。 |
AuthorizationList フィールド
各フィールドは、AIDL インターフェース仕様の Keymaster / KeyMint 承認タグに対応しています。この仕様は、承認タグの信頼できる情報源です(意味、内容の形式、KeyDescription
オブジェクトの softwareEnforced
または hardwareEnforced
フィールドに表示されるかどうか、他のタグと相互に排他的であるかどうか)。AuthorizationList
フィールドはすべて省略可能です。
各フィールドには、Keymaster / KeyMint タグ番号に等しい、コンテキスト固有の EXPLICIT
タグがあります。これにより、AuthorizationList
のデータをコンパクトに表現できます。そのため ASN.1 パーサーは、コンテキスト固有のタグごとに想定されるデータ型を認識している必要があります。たとえば、Tag::USER_AUTH_TYPE
は ENUM | 504
と定義されています。構成証明拡張スキーマでは、AuthorizationList
の purpose
フィールドが userAuthType [504] EXPLICIT INTEGER OPTIONAL
と指定されています。したがって、ASN.1 エンコードには ASN.1 の型 INTEGER
(10
)の UNIVERSAL
クラスタグではなく、コンテキスト固有のタグ 504
が含まれます。
-
purpose
-
Tag::PURPOSE
承認タグに対応し、タグ ID 値 1 を使用します。 -
algorithm
-
Tag::ALGORITHM
承認タグに対応し、タグ ID 値 2 を使用します。構成証明
AuthorizationList
オブジェクト内では、アルゴリズムの値は常にRSA
またはEC
になります。 -
keySize
-
Tag::KEY_SIZE
承認タグに対応し、タグ ID 値 3 を使用します。 -
digest
-
Tag::DIGEST
承認タグに対応し、タグ ID 値 5 を使用します。 -
padding
-
Tag::PADDING
承認タグに対応し、タグ ID 値 6 を使用します。 -
ecCurve
-
Tag::EC_CURVE
承認タグに対応し、タグ ID 値 10 を使用します。Android システムのキーストア内で楕円曲線(EC)キーペアを生成する際に使用されるパラメータ セットで、ECDSA を使用して署名と検証を行います。
-
rsaPublicExponent
-
Tag::RSA_PUBLIC_EXPONENT
承認タグに対応し、タグ ID 値 200 を使用します。 -
mgfDigest
-
キー構成証明バージョンが 100 以上の場合に限り存在します。
Tag::RSA_OAEP_MGF_DIGEST
KeyMint 承認タグに対応し、タグ ID 値 203 を使用します。 -
rollbackResistance
-
キー構成証明バージョン 3 以上の場合に限り存在します。
Tag::ROLLBACK_RESISTANCE
承認タグに対応し、タグ ID 値 303 を使用します。 -
earlyBootOnly
-
キー構成証明バージョン 4 以上の場合に限り存在します。
Tag::EARLY_BOOT_ONLY
承認タグに対応し、タグ ID 値 305 を使用します。 -
activeDateTime
-
Tag::ACTIVE_DATETIME
承認タグに対応し、タグ ID 値 400 を使用します。 -
originationExpireDateTime
-
Tag::ORIGINATION_EXPIRE_DATETIME
Keymaster 承認タグに対応し、タグ ID 値 401 を使用します。 -
usageExpireDateTime
-
Tag::USAGE_EXPIRE_DATETIME
承認タグに対応し、タグ ID 値 402 を使用します。 -
usageCountLimit
-
Tag::USAGE_COUNT_LIMIT
承認タグに対応し、タグ ID 値 405 を使用します。 -
noAuthRequired
-
Tag::NO_AUTH_REQUIRED
承認タグに対応し、タグ ID 値 503 を使用します。 -
userAuthType
-
Tag::USER_AUTH_TYPE
承認タグに対応し、タグ ID 値 504 を使用します。 -
authTimeout
-
Tag::AUTH_TIMEOUT
承認タグに対応し、タグ ID 値 505 を使用します。 -
allowWhileOnBody
-
Tag::ALLOW_WHILE_ON_BODY
承認タグに対応し、タグ ID 値 506 を使用します。ユーザーがデバイスを身に付け続けている場合、認証のタイムアウト期限後もキーを使用できるようにします。セキュアな内蔵センサーにより、ユーザーがデバイスを身に付けているかどうかが判定されます。
-
trustedUserPresenceRequired
-
キー構成証明バージョン 3 以上の場合に限り存在します。
Tag::TRUSTED_USER_PRESENCE_REQUIRED
承認タグに対応し、タグ ID 値 507 を使用します。「ユーザーが物理的存在の証明を提供した場合に限り、このキーが使用可能になる」と指定します。以下はその一例です。
- StrongBox キーの場合、StrongBox デバイス上のピンに組み込まれたハードウェア ボタン。
- TEE キーの場合、TEE がスキャナを排他的に制御し、指紋照合プロセスを実行する間は、指紋認証によって、存在の証明が提供されます。
-
trustedConfirmationRequired
-
キー構成証明バージョン 3 以上の場合に限り存在します。
Tag::TRUSTED_CONFIRMATION_REQUIRED
承認タグに対応し、タグ ID 値 508 を使用します。「承認トークンを使用してデータに署名することをユーザーが同意した場合に限り、キーが使用可能になる」と指定します。ユーザーの同意を取得する方法については、Android Protected の確認をご覧ください。
注: このタグが適用されるのは、
SIGN
目的を使用するキーに限られます。 -
unlockedDeviceRequired
-
キー構成証明バージョン 3 以上の場合に限り存在します。
Tag::UNLOCKED_DEVICE_REQUIRED
承認タグに対応し、タグ ID 値 509 を使用します。 -
allApplications
-
Tag::ALL_APPLICATIONS
承認タグに対応し、タグ ID 値 600 を使用します。デバイス上のすべてのアプリがキーペアにアクセスできるかどうかを示します。
-
applicationId
-
Tag::APPLICATION_ID
承認タグに対応し、タグ ID 値 601 を使用します。 -
creationDateTime
-
Tag::CREATION_DATETIME
承認タグに対応し、タグ ID 値 701 を使用します。 -
origin
-
Tag::ORIGIN
承認タグに対応し、タグ ID 値 702 を使用します。 -
rollbackResistant
-
キー構成証明バージョン 1 およびバージョン 2 の場合に限り存在します。
Tag::ROLLBACK_RESISTANT
承認タグに対応し、タグ ID 値 703 を使用します。 -
rootOfTrust
-
Tag::ROOT_OF_TRUST
承認タグに対応し、タグ ID 値 704 を使用します。詳細については、RootOfTrust データ構造セクションをご覧ください。
-
osVersion
-
Tag::OS_VERSION
承認タグに対応し、タグ ID 値 705 を使用します。Keymaster に関連付けられている Android オペレーティング システムのバージョンが、6 桁の整数で指定されます。たとえば、バージョン 8.1.0 は「080100」になります。
承認リストにこの値が含まれるのは、Keymaster バージョン 1.0 以降に限られます。
-
osPatchLevel
-
Tag::PATCHLEVEL
承認タグに対応し、タグ ID 値 706 を使用します。Keymaster 内で使用されているセキュリティ パッチに関連付けられている年と月が、6 桁の整数で指定されます。たとえば、2018 年 8 月のパッチは「201808」になります。
承認リストにこの値が含まれるのは、Keymaster バージョン 1.0 以降に限られます。
-
attestationApplicationId
-
キー構成証明バージョン 2 以上の場合に限り存在します。
Tag::ATTESTATION_APPLICATION_ID
Keymaster 承認タグに対応し、タグ ID 値 709 を使用します。詳細については、AttestationApplicationId データ構造セクションをご覧ください。
-
attestationIdBrand
-
キー構成証明バージョン 2 以上の場合に限り存在します。
Tag::ATTESTATION_ID_BRAND
Keymaster タグに対応し、タグ ID 値 710 を使用します。 -
attestationIdDevice
-
キー構成証明バージョン 2 以上の場合に限り存在します。
Tag::ATTESTATION_ID_DEVICE
Keymaster タグに対応し、タグ ID 値 711 を使用します。 -
attestationIdProduct
-
キー構成証明バージョン 2 以上の場合に限り存在します。
Tag::ATTESTATION_ID_PRODUCT
Keymaster タグに対応し、タグ ID 値 712 を使用します。 -
attestationIdSerial
-
キー構成証明バージョン 2 以上の場合に限り存在します。
Tag::ATTESTATION_ID_SERIAL
Keymaster タグに対応し、タグ ID 値 713 を使用します。 -
attestationIdImei
-
キー構成証明バージョン 2 以上の場合に限り存在します。
Tag::ATTESTATION_ID_IMEI
承認タグに対応し、タグ ID 値 714 を使用します。 -
attestationIdMeid
-
キー構成証明バージョン 2 以上の場合に限り存在します。
Tag::ATTESTATION_ID_MEID
承認タグに対応し、タグ ID 値 715 を使用します。 -
attestationIdManufacturer
-
キー構成証明バージョン 2 以上の場合に限り存在します。
Tag::ATTESTATION_ID_MANUFACTURER
承認タグに対応し、タグ ID 値 716 を使用します。 -
attestationIdModel
-
キー構成証明バージョン 2 以上の場合に限り存在します。
Tag::ATTESTATION_ID_MODEL
承認タグに対応し、タグ ID 値 717 を使用します。 -
vendorPatchLevel
-
キー構成証明バージョン 3 以上の場合に限り存在します。
Tag::VENDOR_PATCHLEVEL
承認タグに対応し、タグ ID 値 718 を使用します。このキーを使用するためにデバイスにインストールする必要がある、ベンダー イメージのセキュリティ パッチ レベルを指定します。値は「YYYYMMDD」の形式で表示され、ベンダー セキュリティ パッチの日付を示します。たとえば、2018 年 8 月 1 日付けのベンダー セキュリティ パッチがインストールされている Android デバイス上でキーが生成された場合、この値は「20180801」になります。
-
bootPatchLevel
-
キー構成証明バージョン 3 以上の場合に限り存在します。
Tag::BOOT_PATCHLEVEL
承認タグに対応し、タグ ID 値 719 を使用します。このキーを使用するためにデバイスにインストールする必要がある、カーネル イメージのセキュリティ パッチ レベルを指定します。値は「YYYYMMDD」の形式で表示され、システム セキュリティ パッチの日付を示します。たとえば、2018 年 8 月 5 日付けのシステム セキュリティ パッチがインストールされている Android デバイス上でキーが生成された場合、この値は「20180805」になります。
-
deviceUniqueAttestation
-
キー構成証明バージョン 4 以上の場合に限り存在します。
Tag::DEVICE_UNIQUE_ATTESTATION
承認タグに対応し、タグ ID 値 720 を使用します。 -
attestationIdSecondImei
-
キー構成証明バージョン 300 以上の場合に限り存在します。
Tag::ATTESTATION_ID_SECOND_IMEI
承認タグに対応し、タグ ID 値 723 を使用します。
RootOfTrust フィールド
-
verifiedBootKey
- 確認付きブートの一環として、デバイスの起動時に実行されるすべてのコードの整合性と正真性を検証するために使用される、公開鍵のセキュア ハッシュ。SHA-256 が推奨されます。
-
deviceLocked
- デバイスのブートローダーがロックされているかどうか。
true
の場合、デバイスは確認付きブートによって確認された署名付きイメージを起動しています。 -
verifiedBootState
- デバイスの確認付きブートの状態。
-
verifiedBootHash
- 確認付きブートによって保護されるすべてのデータのダイジェスト。Android の確認付きブートのリファレンス実装を使用するデバイスの場合、このフィールドには VBMeta ダイジェストが含まれます。
VerifiedBootState の値
値 | 対応するブート状態 | 意味 |
---|---|---|
Verified |
GREEN |
ハードウェアで保護されたルート オブ トラストから、ブートローダーや、確認付きブートによって確認されたすべてのパーティションに至るまでの、完全な信頼チェーン。この状態の場合、verifiedBootKey フィールドには埋め込みのルート オブ トラストのハッシュ(デバイス メーカーが工場でデバイスの ROM に埋め込んだ証明書)が含まれます。 |
SelfSigned |
YELLOW |
Verified と同様ですが、メーカーが工場で埋め込んだルート オブ トラストではなく、ユーザーが設定したルート オブ トラストを使用して検証が行われる点が異なります。この状態の場合、verifiedBootKey フィールドにはユーザーが設定した公開鍵のハッシュが含まれます。 |
Unverified |
ORANGE |
デバイスのブートローダーがロック解除されているため、信頼チェーンを確立できません。デバイスを自由に変更できるため、デバイスの完全性はユーザーが別途検証する必要があります。この状態の場合、verifiedBootKey フィールドには 32 バイトの 0 が含まれます。 |
Failed |
RED |
デバイスの検証が不合格でした。この状態の場合、他の RootOfTrust フィールドの内容は保証されません。 |
AttestationApplicationId
このフィールドは、構成証明に基づいて秘密鍵マテリアルの使用が認められるアプリに関して、Android プラットフォームの考えを反映したものです。複数のパッケージが同じ UID を共有する場合に限り、複数のパッケージを含めることができます。AuthorizationList
の AttestationApplicationId
フィールドは OCTET_STRING
型であり、以下の ASN.1 スキーマに沿った形式になります。
AttestationApplicationId ::= SEQUENCE { package_infos SET OF AttestationPackageInfo, signature_digests SET OF OCTET_STRING, } AttestationPackageInfo ::= SEQUENCE { package_name OCTET_STRING, version INTEGER, }
package_infos
-
AttestationPackageInfo
オブジェクトのセット。それぞれパッケージの名前とバージョン番号を示します。 signature_digests
-
アプリの署名証明書の SHA-256 ダイジェストのセット。アプリには複数の署名キー証明書チェーンを設定できます。それぞれ「リーフ」証明書がダイジェストされ、
signature_digests
フィールドに設定されます。フィールド名が紛らわしいですが、ダイジェストされたデータはアプリの署名ではなく、アプリの署名証明書です。getPackageInfo()
を呼び出して返されるSignature
クラスの名前が付けられています。サンプルセットのコード スニペットを以下に示します。{SHA256(PackageInfo.signature[0]), SHA256(PackageInfo.signature[1]), ...}
一意の ID
一意の ID はデバイスを識別する 128 ビットの値ですが、限られた期間のみ有効です。値は次のように計算されます。
HMAC_SHA256(T || C || R, HBK)
ここで:
T
は「時間カウンタ値」であり、Tag::CREATION_DATETIME
の値を 2592000000 で割り算して余りを破棄した値として計算されます。T
は 30 日ごとに変更されます(2592000000 = 30 * 24 * 60 * 60 * 1000)。C
はTag::APPLICATION_ID
の値です。R
は、attest_key 呼び出しに対する attest_params パラメータにTag::RESET_SINCE_ID_ROTATION
が存在する場合は 1、このタグが存在しない場合は 0 です。HBK
は、信頼できる実行環境が認識していて絶対に明かすことがない、ハードウェアにバインドされた一意のシークレットです。このシークレットは、少なくとも 128 ビットのエントロピーを含み、個々のデバイスに対して一意です(128 ビットのエントロピーがあれば確率的な一意性が満たされます)。HBK は、HMAC または AES_CMAC を使用して、融合された鍵マテリアルから生成する必要があります。
HMAC_SHA256 出力を切り捨てて 128 ビットにします。
構成証明の鍵と証明書
2 つの鍵(RSA と ECDSA)および対応する証明書チェーンは、セキュアな方法でデバイスにプロビジョニングされます。
Android 12 ではリモートキー プロビジョニングが導入され、Android 13 ではデバイスへの実装が必須になりました。リモートキー プロビジョニングにより、フィールドのデバイスに対し、アプリごとに ECDSA P256 構成証明書が提供されます。これらの証明書は、工場出荷時にプロビジョニングされた証明書よりも有効期間が短くなります。
複数の IMEI
Android 14 では、Android 鍵構成証明レコードに複数の IMEI のサポートが追加されました。OEM は、2 つめの IMEI に KeyMint タグを追加することで、この機能を実装できます。デバイスが複数のセル無線通信を搭載することが一般的となってきており、OEM は 2 つの IMEI を持つデバイスをサポートできるようになりました。
OEM は、デバイスに 2 つめの IMEI が存在する場合、KeyMint の実装に 2 つめの IMEI をプロビジョニングし、それらの実装が最初の IMEI を認証するのと同じ方法で、その IMEI を認証できるようにする必要があります。
プロビジョニング情報拡張データ
プロビジョニング情報拡張データには OID 1.3.6.1.4.1.11129.2.1.30
が付与されています。この拡張データは、プロビジョニング サーバーがデバイスについて把握している情報を示しています。
スキーマ
この拡張データは以下の CDDL スキーマに従います。
{ 1 : int, ; certificates issued }
このマップはバージョンが付与されておらず、新しいオプション フィールドが追加される可能性があります。
-
certs_issued
-
過去 30 日間にデバイスに対して発行された証明書のおおよその数。この値が平均よりも数桁大きい場合、不正使用の可能性があります。
ID 構成証明
Android 8.0 では、Keymaster 3 を備えたデバイスの ID 構成証明をオプションでサポートしています。ID 構成証明を使用すると、デバイスはシリアル番号や IMEI などのハードウェア識別子の証明を提供できます。この機能はオプションであるとはいえ、すべての Keymaster 3 実装でサポートすることを強くおすすめします。これは、デバイスの身元証明ができるということは、真のゼロタッチ リモート構成などのユースケースのセキュリティを強化できることを意味するためです(リモート側は、なりすましデバイスではなく正当なデバイスと通信していることを確信できます)。
ID 構成証明は、デバイスの工場出荷前に、高信頼実行環境(TEE)のみがアクセスできる、デバイスのハードウェア識別子のコピーを作成することによって、利用可能になります。ユーザーは、デバイスのブートローダーをロック解除して、Android フレームワークによって報告されるシステム ソフトウェアと識別子を変更できます。TEE が保持する識別子のコピーは、この方法では操作できません。つまり、デバイス ID 構成証明は、デバイスの元のハードウェア識別子のみを証明することで、なりすましの試みを阻止します。
ID 構成証明のメイン API サーフェスは、Keymaster 2 で導入された既存の鍵構成証明メカニズムを土台にして構築されています。Keymaster が保持する鍵の構成証明書をリクエストするとき、呼び出し元は、デバイスのハードウェア識別子が構成証明書のメタデータに含まれていることを要求できます。鍵が TEE によって保持されている場合、証明書チェーンは既知のルート オブ トラストまで遡ります。この証明書を受け取った側は、証明書とその内容(ハードウェア識別子を含む)が TEE によって作成されたことを確認できます。TEE は、構成証明書にハードウェア識別子を含めることを要求された場合、ストレージに保持されている、工場出荷前に設定された識別子のみを証明します。
ストレージの特性
デバイスの識別子を保持するストレージには、次のような特性が必要です。
- デバイスが工場から出荷される前に、デバイスの元の識別子から生成された値がストレージにコピーされること。
destroyAttestationIds()
メソッドを使用して、識別子から派生したデータのコピーを完全に破棄できること。「完全に破棄」とは、データを完全に削除し、デバイスを工場出荷時の状態にリセットしても、あるいはデバイス上で他のいかなる手順を実行してもそのデータを復元できないようにするという意味です。ユーザーがブートローダーをロック解除し、システム ソフトウェアを変更し、Android フレームワークが報告する識別子を変更したデバイスの場合、これは特に重要です。- RMA 機能を使用して、ハードウェア識別子から派生したデータの新しいコピーを生成できること。それにより、RMA を通過するデバイスは ID 構成証明を再度実行できます。RMA 機能が使用するメカニズムは、ユーザー自身が呼び出せないように保護する必要があります。そうしないと、ユーザーがなりすまし ID の構成証明を取得する可能性があるためです。
- TEE 内の Keymaster TA(TA: 信頼できるアプリ)以外のコードが、ストレージに保存されている識別子派生データを読み取れないこと。
- ストレージが改ざん検出可能であること。ストレージのコンテンツが変更された場合、TEE はそのコンテンツのコピーが破棄された場合と同様に扱い、すべての ID 構成証明の試みを拒否すること。この仕組みは、ストレージに署名または MAC 化を行うことで実装します。下記の説明をご覧ください。
- ストレージが元の識別子を保持しないこと。ID 構成証明にはチャレンジが含まれるため、証明対象の識別子は常に呼び出し元が指定します。TEE は、指定された識別子が元の値と一致していることのみを検証する必要があります。値ではなく元の値のセキュア ハッシュを格納することで、この検証が可能になります。
コンストラクション
上記の特性を持つ実装を作成するには、ID から派生した値を次のコンストラクション S に格納します。ID 値の他のコピーをシステムの正規の場所以外に格納しないでください。デバイスのオーナーは、ルート権限の取得によってこの場所を変更できます。
S = D || HMAC(HBK, D)
ここで:
D = HMAC(HBK, ID1) || HMAC(HBK, ID2) || ... || HMAC(HBK, IDn)
HMAC
は、適切なセキュア ハッシュ(SHA-256 が推奨されます)を使用した HMAC コンストラクションです。HBK
は、他の目的で使用されていない、ハードウェアにバインドされた鍵です。ID1...IDn
は元の ID 値です。特定のインデックスへの特定の値の関連付けは、デバイスによって識別子の数が異なるため、実装に依存します。||
は連結を表します。
HMAC 出力は固定サイズであるため、個々の ID ハッシュまたは D の HMAC を見つけるためのヘッダーなどの構造は必要ありません。実装は、構成証明を実行するために指定された値をチェックするだけでなく、S から D を抽出して S を検証する必要があります。すなわち、HMAC(HBK, D) を計算し、それを S 内の値と比較して、個々の ID が変更されていない / 破損していないことを確認します。また、実装は、すべての個々の ID 要素および S の検証に一定時間の比較を使用する必要があります。比較時間は、指定された ID の数と、テストの任意の部分の正確な一致と無関係に、一定でなければなりません。
ハードウェア識別子
ID 構成証明がサポートするハードウェア識別子は次のとおりです。
- Android で
Build.BRAND
から返されるブランド名 - Android で
Build.DEVICE
から返されるデバイス名 - Android で
Build.PRODUCT
から返される製品名 - Android で
Build.MANUFACTURER
から返されるメーカー名 - Android で
Build.MODEL
から返されるモデル名 - シリアル番号
- すべての無線通信の IMEI
- すべての無線通信の MEID
デバイス ID 構成証明をサポートするために、デバイスは上記の識別子を証明します。Android を実行しているすべてのデバイスは、最初の 6 つの識別子を持っており、構成証明が機能するためにはそれらが必要です。デバイスにセル無線通信が組み込まれている場合、デバイスは無線通信の IMEI と MEID(両方またはいずれか)の構成証明もサポートする必要があります。
ID 構成証明は、鍵構成証明を実行することによってリクエストされます。リクエストでは、証明対象のデバイス識別子を指定します。識別子は次のようにタグ付けされます。
ATTESTATION_ID_BRAND
ATTESTATION_ID_DEVICE
ATTESTATION_ID_PRODUCT
ATTESTATION_ID_MANUFACTURER
ATTESTATION_ID_MODEL
ATTESTATION_ID_SERIAL
ATTESTATION_ID_IMEI
ATTESTATION_ID_MEID
証明対象の識別子は、UTF-8 でエンコードされたバイト文字列です。この形式は、数値識別子にも適用されます。証明対象の識別子は、それぞれ UTF-8 でエンコードされた文字列として表現されます。
デバイスが ID 構成証明をサポートしていない場合(または以前 destroyAttestationIds()
が呼び出されてデバイスが ID を証明できなくなった場合)、これらのタグを 1 つ以上含む鍵構成証明リクエストは ErrorCode::CANNOT_ATTEST_IDS
で失敗します。
デバイスが ID 構成証明をサポートしており、上記のタグが 1 つ以上鍵構成証明リクエストに含まれている場合、TEE は、各タグで指定された識別子がハードウェア識別子のコピーと一致するかどうかを検証します。1 つ以上の識別子が一致しない場合、構成証明全体が ErrorCode::CANNOT_ATTEST_IDS
で失敗します。同じタグを複数回指定するのは有効です。これは、デバイスの無線通信に複数の IMEI がある場合に IMEI を証明するときなどに役立ちます。個々の ATTESTATION_ID_IMEI
で指定された値がデバイスの無線通信の 1 つと一致すれば、構成証明リクエストは有効です。他のすべてのタグについても同様です。
構成証明が成功すると、証明された ID は、上記のスキーマを使用して、発行される構成証書の構成証明拡張(OID 1.3.6.1.4.1.11129.2.1.17)に追加されます。Keymaster 2 の構成証明スキーマの変更点は、コメント付きで太字で表示されています。
Java API
このセクションは、情報提供のみを目的としています。Keymaster の実装者は、Java API を実装することも使用することもありません。下記の説明は、アプリがどのように機能を使用するかを実装者が理解するのための参考情報です。システム コンポーネントはこの機能を別の方法で使用することがあるので、このセクションの説明を規範と見なさないようにご注意ください。