web-dev-qa-db-ja.com

Android Keystoreシステムはどのように保護できますか?

Androidのドキュメント http://developer.Android.com/training/articles/keystore.html を読みますが、詳細が不足しています...

アプリケーションがAndroidKeyStoreを使用してキー(対称または非対称)を生成する場合。

そのキーストアからキーを抽出できますか?

別のアプリケーション(AppB)がAppAによって生成されたキーにアクセスできますか?

キーを紛失する可能性があるのはどの場合ですか?デバイスの出荷時設定へのリセットのみですか?

ありがとう。

22
Anas EL HAJJAJI

通常の KeyStore ファイルまたは Android KeyStore Provider を使用できます。

キーストア(API 1)

KeyStoreファイルを作成する必要があり、それにアクセスするためのシークレットを管理する必要もあります。この秘密は非常に敏感であり、攻撃者から隠すことは困難です。個人的にはAndroidシステムにその責任を委任することを好みます。そのため、次のソリューションよりもこのソリューションを選択しません。

Android KeyStoreプロバイダー(API 18)

このAPIを使用して、Androidでのファイルとシークレットの管理のすべての重い作業を委任します。 OS自体がロック画面PINコード、パスワード、パターン、その他の変数から取得したパスワードを保存するため、パスワードを使用する必要はありません。

デバイスに安全なハードウェアが組み込まれている場合、キーはそこに保存されます(例:Trusted Execution Environment(TEE))KeyInfo#isInsideSecureHardware() メソッドをチェックして、キーがそこに保存されているかどうかを確認できます。このハードウェアメカニズムは、アプリが侵害されたLinuxカーネルで実行された場合に、追加の保護を提供します。

さらに、Android 9(APIレベル28)以降、 StrongBox Keymaster APIが、セキュアなチップ(Google Pixel 3のTitan Mなど)を含むデバイス用に導入されました。 Android 28以降で実行している場合は、 setIsStrongBoxBacked(boolean) メソッドを呼び出して、Androidに使用することを通知するだけです。デバイスで利用できる場合は、前述のTEEソリューションは許容可能ですが、セキュアエレメント(SE)を使用するこのメカニズムは、セキュリティを目的として設計された異なるハードウェア(CPU、メモリ、ストレージなど)に基づいているため、最も安全なメカニズムです。

ここでは、サポートされている場合、StrongBoxを使用して自己署名証明書とキーペアを作成する簡単な例を示します。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, "AndroidKeyStore")
        .apply {
            val certBuilder = KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT)
                .setKeyValidityStart(keyValidityStart)
                .setKeyValidityEnd(keyValidityEnd)
                .setCertificateSerialNumber(BigInteger.valueOf(1L))
                .setCertificateSubject(X500Principal("CN=MyCompany"))

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                initialize(
                    certBuilder
                        .setIsStrongBoxBacked(true) /* Enable StrongBox */
                        .build()
                )
            } else {
                initialize(certBuilder.build())
            }
        }
        .also {
            val keyPair = it.generateKeyPair()
            ...
        }
}

あなたの質問に関して:

そのキーストアからキーを抽出できますか?

それらの両方を使用すると、アプリは PrivateKey を取得し、これがあなたの意味する場合はそれを使用できます。

別のアプリケーション(AppB)がAppAによって生成されたキーにアクセスできますか?

KeyStoreプロバイダーソリューションを使用すると、各アプリはKeyStoreインスタンスまたはエイリアスにのみアクセスできます。代わりに、別のアプリがファイルにアクセスできる場合、通常のキーストアを使用して、攻撃を試みる可能性があります。

どちらの場合、鍵を失う可能性がありますか?デバイスの出荷時設定へのリセットのみですか?

アプリを削除すると、アプリのKeyStoreプロバイダーインスタンスが消去されます。ただし、 Androidの厄介なバグ (Android 5より前に一般的)のため、ユーザーがロック画面のパターンをパスワードに変更したり、単に削除したりすると、パターン、キーストアは完全に破損します。ユーザーがAndroidの設定から「Clear credentials」を実行した場合も同様です。代わりに従来のKeyStoreを使用すると、それを外部ストレージに保存して、デバイスの出荷時設定へのリセット後も保持できます。ただし、前述のように、プロバイダーよりも安全性は低くなります。

私はいくつかの面で間違っているかもしれませんが、これは私が学んだことであり、私は私の経験を共有しました。これがあなたに役立つことを願っています。

29
GoRoS