web-dev-qa-db-ja.com

復号化されたキーをアプリケーションの変数に割り当てることは安全ですか?

暗号化された秘密鍵をサーバーから取得したとしましょう。それを解読して実際の秘密鍵を取得し、解読した鍵をアプリの変数に割り当てます。これに沿った何か:

const encryptedKey = fetchKeyFromServer();
const secretKey = decrypt(encryptedKey);
//Now, the variable secretKey has the actual secret key in memory

さて、これはセキュリティの面で脆弱なことですか?復号化されたキーをメモリに保存したので、誰かがアプリのメモリから読み取ることによって秘密キーを公開できる可能性はありますか?

ただし、復号化されたキーを変数に割り当てない場合、キーをどのように使用すればよいですか?暗号化されたキーを変数に割り当て、それを使用する必要があるたびに復号化することを考えました。しかし、これが最善の方法かどうかはまだわかりません。

22
xenon

はい、それはキーがアプリケーションのメモリに保存されることを意味します。はい、マルウェア(十分な特権を持つ)がそこから読み取る可能性があるというリスクがあります。このリスクは避けがたいものです。鍵を使用したい場合は、ドアをロックした後で家の鍵をポケットに入れるのと同じように、鍵をメモリに入れておく必要があります。

これは通常、1つの理由で大したこととは見なされません。コンピューターにroot権限を持つマルウェアが存在する場合、それはとにかくすでにゲームオーバーです。その時点で何かを安全に保つ方法はありません。キーを復号化しない場合でも、マルウェアは、その復号化に使用されるキーを、格納されている場所から読み取るだけです。

リスクを軽減するためにできることは3つあります。

  • なんらかの [〜#〜] hsm [〜#〜] を使用します。 (これを指摘してくれた [〜#〜] drf [〜#〜] に感謝します。)これは最良のアプローチですが、実現可能性は作業しているプラ​​ットフォームによって異なります。ただし、他のプロセスのメモリを読み取るための十分な権限を持つマルウェアは、おそらくHSMも使用できることに注意してください。したがって、これはマルウェア感染に対する完全な防御策ではありません。
  • キーがメモリ内にある時間を最小限にして、完了後にメモリを上書きして攻撃ウィンドウを縮小します。 ( MSalters が指摘するように、これは思ったほど簡単ではない可能性があります。たとえば、C++では、オプティマイザは読み取られない書き込みを削除する可能性があります。Java文字列は変更できないため、上書きできません。)
  • Vitor が示唆するように、キーが保存されているメモリページをスワップ不可としてマークし、ディスクに書き込まれないようにします。
32
Anders