web-dev-qa-db-ja.com

Android Keystoreの使用

私はAndroid Keystoreを使用して非対称暗号を保存します(非対称キーを含むファイルを復号化するため)。大量のデータセットを暗号化したいので、非対称でしたSDK 23以降、キーストアには対称キーが十分にあります。

  • 従来のHSMでは、暗号化キーにアクセスできません。データを送信するだけで、HSMが暗号化操作を実行します。しかし、Androidでは、キーストアからキーを取得して、手動で(暗号などを使用して)操作を実行します。)安全ですか?
  • 安全でない場合、使用後にメモリからキーを消去することは可能ですか? (たとえば、私の機能の最後に)
  • 安全である場合、リスクは何ですか? RAMウイルスによって破損していますか?
7
AndoKarim

Android Developer docs "Android keystore system" を見てみましょう。KeyStoreオブジェクトの使用方法に応じて、これを分析する必要があります。 Android KeyStore KeyStore.getInstance("AndroidKeyStore")を使用している場合:

1)アプリが実行されているデバイスにハードウェアベースの安全なストレージがある場合、

キーの素材は、Androidデバイスの安全なハードウェア(Trusted Execution Environment(TEE)、Secure Element(SE)など)にバインドされている場合があります。この機能がキーに対して有効になっている場合、そのキー素材が安全なハードウェアの外部に公開されることはありません。

"Android keystore system" の記事では、この機能の使用方法について詳しく説明しています。

2)デバイスにハードウェアベースのセキュアストレージがない場合:

鍵となる資料が申請プロセスに入力されることはありません。アプリケーションがAndroid Keystore keyを使用して暗号化操作を実行すると、バックグラウンドでプレーンテキスト、暗号化テキスト、署名または検証されるメッセージが、暗号化操作を実行するシステムプロセスに送られます。

おそらくこのシステムプロセスはCで記述されており、メモリ管理をより詳細に制御でき、アプリケーションのスコープから外れたときにキーを適切にゼロ化できます(これにより、ガベージコレクターについての怒りが生じます...)

3)何らかの理由で例のようにKeyStore.getInstance("JKS")を使用する場合 ここ -おそらく何らかの理由で秘密鍵にアクセスする必要があるか、または.jksファイルに秘密鍵をロード/格納する必要がある- いいえ、ワイプできません:Javaガベージコレクタは メモリを返すことで有名です)クリアまたはゼロ化せずにOSAndroid開発者ドキュメント から、Dalvikガベージコレクターが異なる動作をするという証拠はありません。

さらに、Javaガベージコレクターのメカニズムの1つは、プログラムによって現在参照されているヒープ変数のコピーを作成し、古いヒープを解放することです。これは、プライベートのコピーがキーは、範囲外になる前でも、オペレーティングシステムに解放される場合があります。


結論:Android KeyStoreオブジェクトが適切に使用されている場合、秘密鍵はTrusted Execution Environment内で安全に保持されます(TEE)、Secure Element(SE))またはシステムプロセス。

何らかの理由で秘密鍵をアプリに持ち込んだ場合、Java/Dalvik/Androidでは、アプリのメモリに何かが入ると、クリアすることがほぼ不可能になるため、すべての賭けは無効になります。またはそれをゼロ化します。

8
Mike Ounsworth

他の回答はすべてをうまくカバーしていますが、1つの側面は誤解されているようです。他の回答が引用したように、...

鍵となる資料は、申請プロセスに入ることはありません。アプリケーションがAndroid Keystore keyを使用して暗号化操作を実行すると、バックグラウンドでプレーンテキスト、暗号化テキスト、署名または検証されるメッセージが、暗号化操作を実行するシステムプロセスに送られます。

つまり、Androidアプリケーションは、サポートされている手段を使用してキーのバイトを取得できません。Android(and Java) Key インターフェースの単一メソッド Key.getEncoded() を介して生の鍵素材にアクセスします。管理されている鍵の場合Android keystore、Key.getEncoded()によってnullが返されます。

本当にキーデータをAndroidKeyStoreにインポートする必要がある場合(たとえば、キーストアがサポートしていない操作を実行する必要がある場合)、それがアプリケーションメモリに残っていないことを確認する方法はすぐにはわかりません。しかし、私はこれを自分でいじっていて、以下を実行すればあなたはかなり安全だと思われます:

  • キーデータがbyte[]または同様のもの(Stringまたはそのデータをコピーする可能性のあるその他のオブジェクトではない)にのみ保存されていることを確認してください。
  • データのコピーを作成しない独自の* KeySpecクラスを実装します(デフォルトのコピーでは、コピーされたデータがプライベートであるため、簡単に消去する方法はありません)。
  • キーデータがキーストアに配置されるとすぐに、キーデータを保持しているbyte[]を上書きします。
  • キービット:ゼロまたはジャンクデータを使用して、別のダミーエントリをキーストアにすぐに格納します。これは、RPCを介してキーストアサービスに送信するデータのパーセル中に作成されたコピーを消去する唯一の方法のようです。

お役に立てれば。

0
Dylan Nicholson