Keystore(Android):アーキテクチャと動作原理

著者: IT Sectr 公開日: 2026-03-14 読了時間: 10 分

Android Keystoreは、暗号鍵をハードウェア分離環境で安全に保存するためのAndroidのシステムメカニズムです。システムはARM TrustZone搭載デバイスでTrusted Execution Environment(TEE)、または専用のSecure Elementを使用してチップレベルで鍵を保護します。Android Open Source Projectによると、Keystoreは安全な環境内で直接鍵を生成し、RSA、EC、AES、HMACアルゴリズムをサポートしています。

重要なポイント

  • Android Keystoreは、暗号鍵をAndroidユーザースペースから分離するKeyStoreプロバイダーです
  • はTEEまたはSecure Element内で生成され、平文のまま安全な環境から出ることはありません
  • Android 9+はパラメーター(purpose、digest、padding、userAuthenticationRequired)を持つKeyGenParameterSpec.Builderを追加します
  • 生体認証による鍵保護では、各操作の前にBiometricPromptによるユーザー確認が必要です
  • Keymaster HALは、TEEまたはSecure Elementで暗号操作を実装するハードウェア抽象化レイヤーです

Android Keystoreとは?

Android Keystoreは、Android API 1(Android 1.0)から実装されている暗号プロバイダーですが、完全なハードウェアサポートはAndroid 4.3(API 18)から登場しました。Keystoreは、オペレーティングシステムが侵害された場合でも、攻撃者が平文で鍵を抽出できないように秘密鍵を安全に保存する問題を解決します。

AndroidにおけるKeyStoreのアーキテクチャ

Android Keystoreのアーキテクチャは、アプリケーションAPI(java.security.KeyStore)、システムサービス(keystoreデーモン)、ハードウェアレベル(Keymaster HAL)の3層で構成されています。アプリケーションは標準のJava Cryptography Architecture(JCA)APIを介してアクセスし、システムサービスはTEEで動作するKeymasterにリクエストをルーティングします。

鍵を使用したすべての暗号操作(署名、復号)はTEEまたはSecure Element内で実行されます。鍵は決して安全な環境から出ることはなく、アプリケーションは鍵を参照するためのハンドル(エイリアス)のみを受け取ります。これは、鍵がプロセスメモリ内でアクセス可能になる可能性があるソフトウェアKeyStoreとの基本的な違いです。

Java KeyStoreとの違い

標準のJKS(Java KeyStore)またはBKS(Bouncy Castle)はパスワードで保護されたファイルに鍵を保存します。Android Keystoreはハードウェア分離環境に鍵を保存し、rootユーザーからも保護されます。JKSはファイルシステムへの直接アクセスに対して脆弱ですが、Android Keystoreはそうではありません。

もう一つの違い:Android Keystoreでは、には生成時に指定された厳格な使用パラメーター(purpose — sign/verify/encrypt/decryptのみ)があります。これらは後から変更できず、鍵の誤用を防ぎます。

Android Keystoreの仕組み

新しい鍵を作成する際、アプリケーションはKeyGenParameterSpec(将来の鍵のすべてのパラメーターを含む)を指定してKeyPairGeneratorまたはKeyGeneratorを呼び出します。システムはリクエストをKeymaster HALに渡し、KeymasterがTEE内で鍵を生成してハンドルを返します。

鍵生成プロセス

KeyGenParameterSpec.Builderメソッドは必須パラメーター(Keystore内の鍵名、目的(PURPOSE_SIGN、PURPOSE_ENCRYPT)、アルゴリズム(RSA、EC、AES))を受け入れます。追加パラメーター:digest(SHA-256)、padding(PKCS7)、userAuthenticationRequired(生体認証)、keyValidityStart/End(時間制限)。

パラメーターを設定した後、KeyPairGenerator.generateKeyPair()はKeyPairを返します。PrivateKeyはKeymasterに操作を委譲するオブジェクトです。公開鍵は抽出できますが、秘密鍵はできません。秘密鍵はTEE内にのみ存在します。

kotlin
import java.security.KeyPairGenerator
import android.security.keystore.KeyGenParameterSpec
import android.security.keystore.KeyProperties

fun generateKey(alias: String) {
    val spec = KeyGenParameterSpec.Builder(alias,
        KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY
    ).setDigests(KeyProperties.DIGEST_SHA256)
     .setSignaturePaddings(KeyProperties.SIGN_PADDING_RSA_PKCS1)
     .setUserAuthenticationRequired(true)
     .build()

    val kpGen = KeyPairGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_RSA,
        "AndroidKeyStore"
    )
    kpGen.initialize(spec)
    kpGen.generateKeyPair()
}

署名と検証

ECDSAまたはRSA-PSSのSignatureは標準APIを介して作成されます:Signature.getInstance(algorithm).initSign(privateKey)。署名操作はTEEで実行され、アプリケーションがデータを渡し、Keymasterがハードウェアで署名して署名を返します。鍵とデータは共有メモリ内で混ざりません。

生体認証による保護では、署名の前にユーザーがBiometricPrompt経由で認証する必要があります。認証が成功しない場合、Keymasterは操作を実行せず、CryptoAuthenticationExceptionを返します。

kotlin
import java.security.KeyStore
import java.security.Signature
import androidx.biometric.BiometricPrompt

fun signWithBiometric(alias: String) {
    val ks = KeyStore.getInstance("AndroidKeyStore")
    ks.load(null)
    val entry = ks.getEntry(alias, null) as KeyStore.PrivateKeyEntry
    val signature = Signature.getInstance("SHA256withRSA")
    signature.initSign(entry.privateKey)
    // BiometricPrompt with CryptoObject(signature)がFaceID/PINを要求
}

KeyStoreストレージの種類

Androidは2つの鍵ストレージモードをサポートしています:ソフトウェア(TEEなしのデバイス)とハードウェア(TEEまたはSecure Element搭載デバイス)。モードはSoCの機能とAndroidバージョンに依存します。

ソフトウェアKeyStore(ソフトウェアのみ)

Trusted Execution Environmentなしのデバイス(Android 4.3以前または低価格SoC)では、鍵はロック画面パスワードから派生したマスター鍵を使用して暗号化されて保存されます。このモードは安全性が低く、暗号操作中に鍵がプロセスメモリ内でアクセス可能になります。

保護レベルはAES-256-GCMを使用したKeyStoreファイルの暗号化に基づいています。暗号鍵はユーザーのパスワードまたはPINからScrypt(高反復回数のPBKDF2)を介して生成されます。

ハードウェアKeyMaster(TEE/Secure Element)

最新のデバイスでは、TEE(ARM TrustZone)でKeymaster 4.xが使用されます。鍵はTrustZone内でのみ生成、保存、使用されます。Linuxカーネルでさえ秘密鍵にアクセスできず、Keymaster HALのみが操作を実行できます。

Secure Element(例:Samsung KnoxのeSEやGoogle Pixel 3+のStrongBox)は、独自のプロセッサとメモリを持つ独立したチップです。Common Criteria EAL 4+認定を受けており、物理的な改ざんに対する保護を含む最大レベルのセキュリティを提供します。

タイプストレージ場所保護レベルAPIからの利用可能
ソフトウェアファイル /data/misc/keystore中 (AES-256)API 1+
Keymaster 3TEE (TrustZone)API 23+
Keymaster 4TEE + Secure I/O非常に高API 28+
StrongBoxハードウェアSecure Element最大API 28+、オプション

KeyStore APIの操作

Android KeystoreはJava Cryptography Architecture(JCA)に統合されています。プロバイダーにアクセスするには、標準のKeyStore.getInstance("AndroidKeyStore")を使用します。APIはAPI 18から利用可能です。

KeyStoreの作成とロード

KeyStore.load(null)メソッドは、アプリケーションのKeyStoreコンテナをロードします。パスワードは不要で、AndroidはアプリケーションコンテキストとそのUIDを使用してアクセス制御を行います。共有UIDが使用されていない限り、各アプリケーションは自身のエントリのみを表示します。

setEntryおよびgetEntryメソッドは、KeyStore.PrivateKeyEntry、SecretKeyEntry、TrustedCertificateEntryを操作します。ProtectionParameterパラメーターはAndroid Keystoreでは常にnullです(保護はシステムレベルで実装されています)。

kotlin
import java.security.KeyStore
import java.security.cert.Certificate
import android.security.keystore.KeyProtection

fun storeSecretKey(alias: String, key: SecretKey) {
    val ks = KeyStore.getInstance("AndroidKeyStore")
    ks.load(null)
    val prot = KeyProtection.Builder(
        KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
    ).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
     .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
     .setUserAuthenticationRequired(true)
     .build()
    ks.setEntry(alias, KeyStore.SecretKeyEntry(key), prot)
}

ストレージタイプの確認

KeyCharacteristicsを使用して、鍵が保存されている環境(ソフトウェアKeyStore、TEE、StrongBox)を判別できます。getKeyCharacteristics()メソッドはフラグのセットを返します:FLAG_HARDWARE(keymaster)、FLAG_SECURE_ELEMENT(StrongBox)、FLAG_TRUSTED_USER_PRESENCE_REQUIRED(生体認証)。

アルゴリズムとセキュリティ

Android Keystoreは、非対称、対称、MACの3つのカテゴリに分かれた幅広い暗号アルゴリズムをサポートしています。特定のアルゴリズムのサポートはKeymaster HALのバージョンに依存します。

サポートされるアルゴリズム

RSA(1024~4096ビット)— 署名(PKCS1、PSS)および暗号化(OAEP、PKCS1)用。EC(P-224、P-256、P-384、P-521)— ECDSA署名およびECDH鍵合意用。AES(128、256ビット)— CBC、CTR、GCMモードでの対称暗号化用。HMAC(SHA1、SHA256、SHA512)— メッセージ認証用。

に対して、setPurposesが指定され、可能な操作を制限します。PURPOSE_SIGNのRSA鍵は、攻撃者がAPIにアクセスできる場合でも暗号化に使用できません。これはハードウェアレベルでの鍵使用の強制です。

侵害からの保護

Keymasterには、生体認証の失敗試行回数のカウンターが含まれています。指定された失敗回数(setInvalidatedByBiometricEnrollmentで設定可能)を超えると、鍵は使用できなくなり、削除/再生成が必要になります。すべての生体認証テンプレートが削除されると、userAuthenticationRequired=trueのすべての鍵が自動的に無効化されます。

Key Attestation(Android 8.1+)もサポートされています。アプリケーションのリクエストに応じて、Keymasterは鍵の特性(ハードウェア/ソフトウェア、アルゴリズム、目的)に関する情報を含む証明書に署名します。サーバーはこの証明書を検証して、鍵が信頼できる環境で作成されたことを確認できます。

よくある質問

Android KeystoreとJava KeyStoreの違いは何ですか?

Java KeyStoreはパスワードで保護されたファイル(JKS、BKS)に鍵を保存します。Android KeystoreはTEEまたはSecure Elementを介したハードウェア分離を使用します。Java KeyStoreはrootアクセスに対して脆弱ですが、Android Keystoreは秘密鍵が安全な環境から出ることはないため脆弱ではありません。

既存の鍵をAndroid Keystoreにインポートできますか?

はい、KeyProtectionを指定してKeyStore.setEntryを使用することで可能です。ただし、インポートされた鍵にはハードウェア保護がなく、マスター鍵で暗号化されたソフトウェアKeystoreに保存されます。最大限のセキュリティを得るには、常にKeystore内で鍵を生成してください。

デバイスがハードウェアKeyStoreをサポートしているかどうかを確認する方法は?

KeyChain.isBoundKeyAlgorithmを使用するか、鍵生成後にKeyCharacteristicsを確認してください。特性にFLAG_HARDWAREが含まれている場合、鍵がTEEで作成されたことを意味します。また、android.security.keystore.isHardwareBacked()も確認できます。

アプリケーションをアンインストールすると鍵はどうなりますか?

アプリケーションがアンインストールされると、AndroidはKeystoreからそのすべての鍵を削除します。データは元に戻せない形で失われます。再インストール時には、アプリケーションは新しい鍵を生成する必要があります。TEEを介した鍵のバックアップはアーキテクチャ上不可能です。

KeyStoreはデバッグ攻撃からどのように保護しますか?

ロックされたデバイスでは、Keymasterは操作を実行しません。userAuthenticationRequired=trueの鍵は毎回生体認証確認を必要とします。rootアクセスがあっても、攻撃者は直接Keymasterを呼び出すことはできず、Android Keystoreサービスのみを介してアクセスできます。

まとめ

  • Android Keystoreは、TEEまたはSecure Elementを介したハードウェア鍵分離を備えたJCA暗号プロバイダーです
  • はTrustZone内で生成され、平文のまま安全な環境から出ることはありません
  • KeyGenParameterSpecは鍵パラメーターを定義します:purpose、digest、padding、userAuthenticationRequired、keyValidity
  • Keymaster HALは3つのレベルを実装します:ソフトウェア、TEE(Keymaster 3/4)、StrongBox(ハードウェアSecure Element)
  • 生体認証による鍵保護は、setUserAuthenticationRequiredとCryptoObjectを使用したBiometricPromptを介して提供されます
  • Key Attestation(API 28+)により、鍵がハードウェア環境で作成されたことをサーバー側で検証できます
  • Androidアプリケーションでの署名、暗号化、認証用の秘密鍵の保存にはAndroid Keystoreを使用してください

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください