このページには、Android 6.0 以降のキーストアの暗号化機能に関する情報が含まれています。
暗号プリミティブ
キーストアは次のカテゴリの操作を提供します。
- 鍵の生成
- 非対称キーのインポートとエクスポート (キーのラッピングなし)
- 未加工の対称キーのインポート (キーのラッピングなし)
- 適切なパディングモードによる非対称暗号化と復号化
- ダイジェストおよび適切なパディング モードによる非対称署名と検証
- AEAD モードを含む適切なモードでの対称暗号化と復号化
- 対称メッセージ認証コードの生成と検証
目的、モード、パディングなどのプロトコル要素とアクセス制御制約は、キーの生成またはインポート時に指定され、永続的にキーにバインドされ、キーが他の方法で使用できないようにします。
上記のリストに加えて、Keymaster 実装が提供するサービスがもう 1 つありますが、これは API として公開されていません: 乱数生成です。これは、キー、初期化ベクトル (IV)、ランダム パディング、およびランダム性を必要とする安全なプロトコルのその他の要素の生成に内部的に使用されます。
必要なプリミティブ
すべての Keymaster 実装は以下を提供します。
- RSA
- 2048、3072、および 4096 ビットのキーのサポート
- 公開指数 F4 (2^16+1) のサポート
- RSA 署名のパディング モード:
- RSASSA-PSS (
PaddingMode::RSA_PSS
) - RSASSA-PKCS1-v1_5 (
PaddingMode::RSA_PKCS1_1_5_SIGN
)
- RSASSA-PSS (
- RSA 署名のダイジェスト モード:
- SHA-256
- RSA 暗号化/復号化のパディング モード:
- パッドなし
- RSAES-OAEP (
PaddingMode::RSA_OAEP
) - RSAES-PKCS1-v1_5 (
PaddingMode::RSA_PKCS1_1_5_ENCRYPT
)
- ECDSA
- 224、256、384、および 521 ビットのキーのサポートがサポートされており、それぞれ NIST P-224、P-256、P-384、および P-521 曲線を使用します。
- ECDSA のダイジェスト モード:
- ダイジェストなし (非推奨、将来削除される予定)
- SHA-256
- AES
- 128 ビットおよび 256 ビットのキーがサポートされています
- CBC 、CTR、ECB、および GCM。 GCM 実装では、96 ビット未満のタグや 96 ビット以外のノンス長の使用は許可されません。
- パディング モード
PaddingMode::NONE
およびPaddingMode::PKCS7
は、CBC モードと ECB モードでサポートされています。パディングがない場合、入力がブロック サイズの倍数でない場合、CBC または ECB モードの暗号化は失敗します。
- HMAC SHA-256 、任意のキー サイズは少なくとも 32 バイトまで。
Keymaster の実装には、SHA1 および SHA2 ファミリの他のメンバー (SHA-224、SHA384、および SHA512) が強く推奨されます。ハードウェアの Keymaster 実装がそれらを提供しない場合、キーストアはソフトウェアでそれらを提供します。
他のシステムとの相互運用性のために、いくつかのプリミティブも推奨されます。
- RSA のより小さいキー サイズ
- RSA の任意の公開指数
キーアクセス制御
デバイスから決して抽出できないハードウェア ベースのキーは、攻撃者が自由に使用できる場合、あまりセキュリティを提供しません (ただし、抽出できるキーよりも安全です)。したがって、キーストアがアクセス制御を強制することが重要です。
アクセス制御は、タグと値のペアの「認可リスト」として定義されます。認可タグは 32 ビット整数であり、値はさまざまなタイプです。一部のタグは、複数の値を指定するために繰り返される場合があります。タグを繰り返してもよいかどうかは、タグのドキュメントに指定されています。キーが作成されるとき、呼び出し元は認可リストを指定します。キーストアの基礎となる Keymaster 実装はリストを変更して、キーにロールバック保護があるかどうかなどの追加情報を指定し、返されたキー BLOB にエンコードされた「最終的な」認可リストを返します。最終的な認証リストが変更されている場合、暗号化操作にキーを使用しようとしても失敗します。
Keymaster 2 以前の場合、使用可能なタグのセットは列挙型keymaster_authorization_tag_t
で定義されており、永続的に固定されています (ただし、拡張することはできます)。名前にはKM_TAG
接頭辞が付けられました。タグ ID の上位 4 ビットは、タイプを示すために使用されます。
Keymaster 3 は、 KM_TAG
プレフィックスをTag::
に変更しました。
考えられるタイプは次のとおりです。
ENUM
:多くのタグの値は列挙で定義されます。たとえば、 TAG::PURPOSE
の可能な値は enum keymaster_purpose_t
で定義されます。
ENUM_REP
:認可リスト内でタグを繰り返すことができる点を除いて、 ENUM
と同じです。繰り返しは、複数の許可された値を示します。たとえば、暗号化キーにはKeyPurpose::ENCRYPT
とKeyPurpose::DECRYPT
含まれる可能性があります。
UINT
: 32 ビットの符号なし整数。例: TAG::KEY_SIZE
UINT_REP
:タグが認可リスト内で繰り返される場合がある点を除いて、 UINT
と同じです。繰り返しは、複数の許可された値を示します。
ULONG
: 64 ビットの符号なし整数。例: TAG::RSA_PUBLIC_EXPONENT
ULONG_REP
: ULONG
と同じですが、認可リスト内でタグを繰り返すことができる点が異なります。繰り返しは、複数の許可された値を示します。
DATE
: 1970 年 1 月 1 日からのミリ秒単位で表される日付/時刻値。例: TAG::PRIVKEY_EXPIRE_DATETIME
BOOL
:真または偽。 BOOL
型のタグは、タグが存在しない場合は「false」、存在する場合は「true」とみなされます。例: TAG::ROLLBACK_RESISTANT
BIGNUM
:ビッグエンディアン順のバイト配列として表現される任意の長さの整数。例: TAG::RSA_PUBLIC_EXPONENT
BYTES
:バイトのシーケンス。例: TAG::ROOT_OF_TRUST
ハードウェアとソフトウェアの施行
すべての安全なハードウェア実装に同じ機能が含まれているわけではありません。さまざまなアプローチをサポートするために、Keymaster は、安全な世界アクセス制御の実施と非安全な世界アクセス制御の実施、またはハードウェアとソフトウェアの実施をそれぞれ区別します。
すべての実装:
- すべての承認の完全一致を強制します (強制ではありません)。キー BLOB 内の承認リストは、順序も含め、キーの生成中に返される承認と正確に一致します。不一致があると、診断エラーが発生します。
- セマンティック値が強制される承認を宣言します。
ハードウェア強制承認を宣言するための API メカニズムは、 keymaster_key_characteristics_t
構造内にあります。これは、認可リストを 2 つのサブリストhw_enforced
とsw_enforced
に分割します。安全なハードウェアは、強制できる内容に基づいて、それぞれに適切な値を配置する責任があります。
さらに、キーストアは、安全なハードウェアによって強制されるかどうかに関係なく、すべての承認のソフトウェア ベースの強制を実装します。
たとえば、キーの有効期限をサポートしない TrustZone ベースの実装を考えてみましょう。有効期限のあるキーがまだ作成される可能性があります。そのキーの認証リストには、有効期限を含むタグTAG::ORIGINATION_EXPIRE_DATETIME
が含まれます。キーストアへのキー特性のリクエストにより、 sw_enforced
リスト内でこのタグが検索され、安全なハードウェアは有効期限要件を強制しません。ただし、有効期限が切れたキーを使用しようとすると、キーストアによって拒否されます。
その後、有効期限をサポートする安全なハードウェアでデバイスがアップグレードされた場合、キー特性のリクエストはhw_enforced
リストでTAG::ORIGINATION_EXPIRE_DATETIME
を見つけ、キーストアが何らかの理由で破壊またはバイパスされた場合でも、有効期限が切れた後にキーを使用しようとすると失敗します。 。
キーがハードウェアでサポートされているかどうかを判断する方法の詳細については、 「キーの構成証明」を参照してください。
暗号メッセージ構築の承認
次のタグは、関連付けられたキーを使用した操作の暗号化特性を定義するために使用されます: TAG::ALGORITHM
、 TAG::KEY_SIZE
、 TAG::BLOCK_MODE
、 TAG::PADDING
、 TAG::CALLER_NONCE
、およびTAG::DIGEST
TAG::PADDING
、 TAG::DIGEST
、およびPaddingMode::BLOCK_MODE
は反復可能です。つまり、複数の値を 1 つのキーに関連付けることができ、使用される値は操作時に指定されます。
目的
キーには関連する一連の目的があり、キーの使用方法を定義するタグTAG::PURPOSE
を持つ 1 つ以上の認可エントリとして表現されます。目的は次のとおりです。
-
KeyPurpose::ENCRYPT
-
KeyPurpose::DECRYPT
-
KeyPurpose::SIGN
-
KeyPurpose::VERIFY
どのキーにも、これらの目的のサブセットを含めることができます。組み合わせによってはセキュリティ上の問題が発生することに注意してください。たとえば、暗号化と署名の両方に使用できる RSA キーを使用すると、攻撃者はシステムに任意のデータを復号化させて署名を生成させることができます。
輸入と輸出
Keymaster は、X.509 形式での公開キーのみのエクスポートと、以下のインポートをサポートします。
- パスワードベースの暗号化を行わない、DER でエンコードされた PKCS#8 形式の公開キーと秘密キーのペア
- 生のバイトとしての対称キー
インポートされたキーが安全に生成されたキーと確実に区別できるようにするために、 TAG::ORIGIN
適切なキー認証リストに含まれています。たとえば、キーがセキュア ハードウェアで生成された場合、値KeyOrigin::GENERATED
を持つTAG::ORIGIN
がキー特性のhw_enforced
リストに見つかりますが、セキュア ハードウェアにインポートされたキーの値はKeyOrigin::IMPORTED
になります。 KeyOrigin::IMPORTED
。
ユーザ認証
Secure Keymaster の実装はユーザー認証を実装しませんが、ユーザー認証を実装する他の信頼できるアプリに依存します。これらのアプリが実装するインターフェイスについては、 「Gatekeeper」ページを参照してください。
ユーザー認証要件は、2 セットのタグを介して指定されます。最初のセットは、どのユーザーがキーを使用できるかを示します。
-
TAG::ALL_USERS
キーがすべてのユーザーによって使用可能であることを示します。存在する場合、TAG::USER_ID
とTAG::USER_SECURE_ID
は存在しません。 -
TAG::USER_ID
許可されたユーザーの ID を指定する数値が入ります。これはアプリケーション UID ではなく Android ユーザー ID (マルチユーザー用) であり、安全でないソフトウェアによってのみ適用されることに注意してください。存在する場合、TAG::ALL_USERS
は存在しません。 -
TAG::USER_SECURE_ID
キーの使用をロック解除するために安全な認証トークンで提供される安全なユーザー ID を指定する 64 ビットの数値があります。繰り返した場合、いずれかの値が安全な認証トークンで提供されている場合、キーが使用される可能性があります。
2 番目のセットは、ユーザーを認証する必要があるかどうか、またいつ認証する必要があるかを示します。これらのタグがどちらも存在せず、 TAG::USER_SECURE_ID
が存在する場合は、キーを使用するたびに認証が必要です。
-
NO_AUTHENTICATION_REQUIRED
ユーザー認証が必要ないことを示しますが、キーはTAG::USER_ID
で指定されたユーザーとして実行されているアプリによってのみ使用できます。 -
TAG::AUTH_TIMEOUT
、キーの使用を許可するために必要なユーザー認証の最新性を秒単位で指定する数値です。これは、秘密キー/秘密キーの操作にのみ適用されます。公開キーの操作には認証は必要ありません。タイムアウトは再起動をまたいで発生しません。再起動後は、すべてのキーは「認証されません」。タイムアウトは、起動ごとに 1 回認証が必要であることを示すために大きな値に設定されている可能性があります (2^32 秒は約 136 年です。おそらく、Android デバイスはそれよりも頻繁に再起動されます)。
クライアントバインディング
特定のクライアント アプリケーションとキーの関連付けであるクライアント バインディングは、オプションのクライアント ID といくつかのオプションのクライアント データ (それぞれTAG::APPLICATION_ID
とTAG::APPLICATION_DATA
) を介して行われます。キーストアはこれらの値を不透明な BLOB として扱い、キーの生成/インポート中に提示された同じ BLOB がすべての使用に対して提示され、バイトごとに同一であることのみを保証します。クライアント バインディング データは Keymaster から返されません。呼び出し側はキーを使用するためにそれを知っている必要があります。
この機能はアプリケーションには公開されません。
有効期限
キーストアは、日付によるキーの使用制限をサポートしています。キーの有効性の開始とキーの有効期限をキーに関連付けることができ、現在の日付/時刻が有効な範囲外の場合、Keymaster はキー操作の実行を拒否します。キーの有効範囲は、タグTAG::ACTIVE_DATETIME
、 TAG::ORIGINATION_EXPIRE_DATETIME
、およびTAG::USAGE_EXPIRE_DATETIME
で指定されます。 「作成」と「使用」の区別は、キーが新しい暗号文/署名などを「作成」するために使用されているか、既存の暗号文/署名などを「使用」するために使用されているかに基づいています。この区別はアプリケーションには公開されないことに注意してください。
TAG::ACTIVE_DATETIME
、 TAG::ORIGINATION_EXPIRE_DATETIME
、およびTAG::USAGE_EXPIRE_DATETIME
タグはオプションです。タグが存在しない場合は、問題のキーを常にメッセージの復号化/検証に使用できると想定されます。
実時間は安全ではない世界によって提供されるため、有効期限関連のタグがハードウェア強制リストに含まれる可能性は低いです。ハードウェアによる有効期限の強制には、安全な世界が何らかの方法で信頼できる時刻とデータを取得する必要があります。たとえば、信頼できるリモート タイムサーバーを使用したチャレンジ応答プロトコルを介してです。
ルートオブトラストバインディング
キーストアでは、キーがルート オブ トラストにバインドされている必要があります。ルート オブ トラストは、起動時に (できればブートローダーによって) Keymaster セキュア ハードウェアに提供されるビット文字列です。このビット文字列は、Keymaster によって管理されるすべてのキーに暗号的にバインドされます。
ルート オブ トラストは、ブート イメージの署名とデバイスのロック状態を検証するために使用される公開キーで構成されます。別のシステム イメージを使用できるように公開キーが変更された場合、またはロック状態が変更された場合、以前の信頼のルートが復元され、システムが復元されない限り、以前のシステムによって作成されたキーマスターで保護されたキーは使用できなくなります。そのキーで署名されたものがブートされます。目標は、攻撃者がインストールしたオペレーティング システムがキーマスター キーを使用できないようにすることで、ソフトウェアによるキー アクセス制御の価値を高めることです。
スタンドアロンキー
一部の Keymaster セキュア ハードウェアは、キー マテリアルを内部に保存し、暗号化されたキー マテリアルではなくハンドルを返すことを選択する場合があります。あるいは、他の非セキュアまたはセキュア ワールド システム コンポーネントが利用可能になるまでキーを使用できない場合もあります。 Keymaster HAL を使用すると、呼び出し元はTAG::STANDALONE
タグを介してキーを「スタンドアロン」にすることを要求できます。これは、BLOB と実行中の Keymaster システム以外のリソースが必要ないことを意味します。キーに関連付けられたタグを検査して、キーがスタンドアロンであるかどうかを確認できます。現時点では、次の 2 つの値のみが定義されています。
-
KeyBlobUsageRequirements::STANDALONE
-
KeyBlobUsageRequirements::REQUIRES_FILE_SYSTEM
この機能はアプリケーションには公開されません。
速度
作成時に、最大使用速度をTAG::MIN_SECONDS_BETWEEN_OPS
で指定できます。 TrustZone 実装は、操作がTAG::MIN_SECONDS_BETWEEN_OPS
秒未満前に実行された場合、そのキーを使用した暗号化操作の実行を拒否します。
速度制限を実装する簡単なアプローチは、キー ID と最終使用タイムスタンプのテーブルです。このテーブルのサイズは限られている可能性がありますが、少なくとも 16 個のエントリを収容できます。テーブルがいっぱいで、更新または破棄できるエントリがない場合、セキュアなハードウェア実装は「フェイルセーフ」で、エントリの 1 つが期限切れになるまで速度制限のあるすべてのキー操作を拒否することを好みます。再起動時にすべてのエントリが期限切れになっても構いません。
TAG::MAX_USES_PER_BOOT
を使用すると、キーの使用をブートごとにn回に制限することもできます。これには、少なくとも 4 つのキーを収容し、フェイルセーフを備えた追跡テーブルも必要です。アプリケーションはブートごとに制限されたキーを作成できないことに注意してください。この機能はキーストアを通じて公開されず、システム操作用に予約されています。
この機能はアプリケーションには公開されません。
乱数ジェネレーターの再シード
安全なハードウェアはキーマテリアルと初期化ベクトル (IV) の乱数を生成し、またハードウェア乱数ジェネレーターは常に完全に信頼できるとは限らないため、Keymaster HAL は、クライアントがランダムな乱数に混合される追加のエントロピーを提供できるようにするインターフェイスを提供します。生成された数値。
ハードウェア乱数ジェネレータをプライマリ シード ソースとして使用します。外部 API を通じて提供されるシード データを、数値生成に使用されるランダム性の唯一のソースにすることはできません。さらに、使用される混合操作では、シード ソースのいずれかが予測不可能な場合に、ランダム出力が予測不可能であることを保証する必要があります。
この機能はアプリケーションには公開されませんが、Java SecureRandom インスタンスから取得した追加のエントロピーを安全なハードウェアに定期的に提供するフレームワークによって使用されます。