認証

Android は、ユーザー認証ゲート型暗号キーの概念を使用しており、次のコンポーネントが必要です。

  • 暗号化キーのストレージおよびサービス プロバイダー。暗号化キーを保存し、それらのキーに基づいて標準の暗号化ルーチンを提供します。 Android は、Trusted Execution Environment (TEE) や Strongbox などの Secure Element (SE) を含むキー ストレージ用のハードウェア ベースの暗号化を含む、暗号化サービス用のハードウェア ベースのキーストアとキーマスターをサポートしています。
  • ユーザー認証システム。ユーザーの存在および/または認証の成功を証明します。 Android は、PIN/パターン/パスワード認証のGatekeeperと指紋認証のFingerprintをサポートしています。 Android 9 以降を搭載したデバイスは、指紋および追加の生体認証の単一の統合ポイントとしてBiometricPromptを使用できます。これらのコンポーネントは、認証されたチャネルを通じてキーストア サービスと認証状態を通信します。 (フレームワーク レベルのAndroid キーストア システムもキーストア サービスによってサポートされています。)

ゲートキーパー、指紋、および生体認証コンポーネントは、キーストアおよびその他のコンポーネントと連携して、ハードウェア ベースの認証トークン(AuthToken) の使用をサポートします。

登録

工場出荷時設定にリセットした後のデバイスの最初の起動時に、すべての認証システムがユーザーから資格情報の登録を受け取る準備が整います。ユーザーは最初に PIN/パターン/パスワードを Gatekeeper に登録する必要があります。この初期登録では、ユーザーの識別子として、またユーザーの暗号化マテリアルのバインド トークンとして機能する、ランダムに生成された 64 ビットのユーザー セキュア識別子 (SID) が作成されます。このユーザー SID は、ユーザーのパスワードに暗号的にバインドされています。 Gatekeeper への認証が成功すると、そのパスワードのユーザー SID を含む AuthToken が生成されます。

資格情報を変更したいユーザーは、既存の資格情報を提示する必要があります。既存の資格情報が正常に検証されると、既存の資格情報に関連付けられたユーザー SID が新しい資格情報に転送され、ユーザーは資格情報を変更した後もキーにアクセスし続けることができます。ユーザーが既存の資格情報を提示しない場合、新しい資格情報は完全にランダムなユーザー SID で登録されます。ユーザーはデバイスにアクセスできますが、古いユーザー SID で作成されたキーは永久に失われます。これは、信頼できない登録として知られています。

通常の状況では、Android フレームワークは信頼できない登録を許可しないため、ほとんどのユーザーがこの機能を目にすることはありません。ただし、デバイス管理者または攻撃者による強制的なパスワードのリセットにより、この問題が発生する可能性があります。

認証

ユーザーは資格情報を設定し、ユーザー SID を受け取った後、認証を開始できます。認証は、ユーザーが PIN、パターン、パスワード、または指紋を入力すると始まります。すべての TEE コンポーネントは、相互のメッセージを認証するために使用する秘密キーを共有します。

認証の流れ
図 1.認証フロー
  1. ユーザーが認証方法を提供すると、関連するサービスが関連するデーモンにリクエストを行います。
    • PIN、パターン、またはパスワードの場合、 LockSettingsService gatekeeperdにリクエストを作成します。
    • 生体認証ベースの認証フローは Android のバージョンによって異なります。 Android 8.x 以前を実行しているデバイスでは、 FingerprintService fingerprintdにリクエストを作成します)。 Android 9 以降を実行しているデバイスでは、 BiometricPromptFingerprintManagerFaceManagerなどの適切なBiometric Managerクラスを使用して、適切な生体認証デーモン (たとえば、指紋の場合はfingerprintdfacedの場合は Faced) にリクエストを作成します。バージョンに関係なく、生体認証はリクエストの送信後に非同期で行われます。
  2. デーモンは対応するデーモンにデータを送信し、AuthToken を生成します。
    • PIN/パターン/パスワード認証の場合、 gatekeeperd PIN、パターン、またはパスワード ハッシュを TEE の Gatekeeper に送信します。 TEE での認証が成功すると、TEE のゲートキーパーは、対応するユーザー SID (AuthToken HMAC キーで署名) を含む AuthToken を Android OS の対応するゲートキーパーに送信します。
    • 指紋認証の場合、 fingerprintd指紋イベントをリッスンし、データを TEE の Fingerprint に送信します。 TEE での認証が成功すると、TEE の Fingerprint は AuthToken (AuthToken HMAC キーで署名) を Android OS の対応する相手に送信します。
    • 他の生体認証の場合、適切な生体認証デーモンが生体認証イベントをリッスンし、それを適切な生体認証 TEE コンポーネントに送信します。
  3. デーモンは署名された AuthToken を受け取り、それをキーストア サービスのバインダー インターフェイスの拡張機能を通じてキーストア サービスに渡します。 ( gatekeeperdデバイスが再ロックされたとき、およびデバイスのパスワードが変更されたときにもキーストア サービスに通知します。)
  4. キーストア サービスは、AuthToken を Keymaster に渡し、Gatekeeper とサポートされている生体認証 TEE コンポーネントと共有されるキーを使用して検証します。 Keymaster は、トークン内のタイムスタンプを最後の認証時刻として信頼し、キーのリリースの決定 (アプリにキーの使用を許可する) をタイムスタンプに基づいて行います。

認証トークンの形式

言語およびコンポーネント間のトークンの共有と互換性を確保するために、 AuthToken 形式はhw_auth_token.hに記述されています。この形式は、固定サイズのフィールドを備えた単純なシリアル化プロトコルです。

分野タイプ必須説明
認証トークンのバージョン1バイトはい以下のすべてのフィールドのグループタグ。
チャレンジ64ビット符号なし整数いいえリプレイ攻撃を防ぐためのランダムな整数。通常は、要求された暗号化操作の ID です。現在、トランザクション指紋認証で使用されています。 AuthToken が存在する場合、AuthToken は同じチャレンジを含む暗号化操作に対してのみ有効です。
ユーザーSID 64ビット符号なし整数はいデバイス認証に関連付けられたすべてのキーに暗号的に関連付けられた非反復ユーザー識別子。詳細については、 「ゲートキーパー」を参照してください。
認証者 ID (ASID)ネットワーク順序の 64 ビット符号なし整数いいえ特定の認証ポリシーにバインドするために使用される識別子。すべての認証システムには独自の ASID 値があり、独自の要件に応じて変更できます。
認証子の種類ネットワーク順序の 32 ビット符号なし整数はい
  • 0x00 はゲートキーパーです。
  • 0x01 は指紋です。
タイムスタンプネットワーク順序の 64 ビット符号なし整数はい最後にシステムを起動してからの時間 (ミリ秒単位)。
認証トークン HMAC (SHA-256) 256 ビット BLOBはいHMAC フィールドを除くすべてのフィールドのキー付き SHA-256 MAC。

デバイスのブートフロー

デバイスを起動するたびに、AuthToken HMAC キーを生成し、すべての TEE コンポーネント (ゲートキーパー、キーマスター、サポートされている生体認証トラストレット) と共有する必要があります。したがって、リプレイ攻撃に対する保護を強化するには、デバイスが再起動するたびに HMAC キーをランダムに生成する必要があります。

この HMAC キーをすべてのコンポーネントと共有するためのプロトコルは、プラットフォームに依存する実装機能です。キーは TEE の外部で使用できるようにしてはなりません。 TEE OS に内部プロセス間通信 (IPC) メカニズムがなく、信頼できない OS 経由でデータを転送する必要がある場合、転送は安全なキー交換プロトコルを通じて行う必要があります。

Android の隣で実行されるTrustyオペレーティング システムは TEE の一例ですが、代わりに他の TEE を使用することもできます。 Trusty は、内部 IPC システムを使用して、Keymaster と Gatekeeper または適切な生体認証トラストレットの間で直接通信します。 HMAC キーは Keymaster 内にのみ保管されます。フィンガープリントとゲートキーパーは、使用するたびに Keymaster にキーを要求し、値を保持したりキャッシュしたりしません。

一部の TEE には IPC インフラストラクチャがないため、TEE 内のアプレット間で通信は発生しません。これにより、キーストア サービスはシステム内の認証テーブルを認識しているため、失敗する可能性があるリクエストを迅速に拒否することもでき、コストがかかる可能性がある TEE への IPC を節約できます。