web-dev-qa-db-ja.com

Webアプリケーション暗号化キー管理

簡単に言えば、データベースにいくつかの情報を暗号化されたデータとして保存するWebアプリケーションを考えてみましょう。私は意図的にこれをいくつかの一般的なものにしようとしていますが、いくつかの仮定があります:

  • 暗号化されたデータはデータベースにのみ保存されます(他の場所には保存されません)。特定のレコードの一部のフィールドは暗号化されていますが、一部は暗号化されていません。
  • Webアプリは暗号化されたデータをデータベースに書き込む必要があります。
  • Webアプリは、暗号化されたデータを読み取って表示できる必要があります。データは、アプリの認証および承認済み管理セクションにのみ表示されます。
  • データは機密情報であり、データが公開/アクセスされた場合(キーなし*)に備えて保護する必要があります。

質問:

  • 暗号化に使用される鍵はどこに/どのように保存しますか?まず、Webサーバーとデータベースサーバーが同じシステムで、キーをどのように管理しますか?次に、WebサーバーとDBサーバーが分離しているシステムでは、キーをどのように管理しますか?
  • キーはアクセス許可が制限されたファイルですか?別のツール/ソフトウェアに保存されていますか?暗号化キーが暗号化されることもあるが、それがどこで役立つかは明確ではないことを私は見た。

これはかなり基本的なセキュリティの質問であることを知っているので、おそらく私が見逃しているリソースがあれば、それも非常に役立ちます。 Webアプリのセキュリティに関する情報(OWASP、PCI DSSなど)に基づいてこの情報を把握するために(何年にもわたって)多くの時間を費やしてきましたが、この情報は非常に一般的です(例:「データを保護する」 "、"データを暗号化する ")または非常に具体的(" AESで何かを暗号化するには、これを行う... ")。

*これは完全なセキュリティソリューションではないことを理解しています。この情報を取得してデコードする方法がいくつかあることを理解しています。私はこれがその観点から悪い質問かもしれないことを認めます:)

この質問への仮定に関する詳細情報を追加するために編集されました

47
Rob

暗号化に使用する鍵はどこに/どのように保存しますか?

SQLやOracleデータベースなどの組み込みの暗号化を使用している場合の標準的なアプローチでは、データベースが暗号化キーを生成し、これを別のキー保護キーまたはマスターキーで暗号化します。これは、パスフレーズか、たとえば、 .pemファイル。

これは通常、root/Administratorとデータベースサービスアカウントのみがアクセスできる制限されたディレクトリに保存されます。データベースの起動時に、キーが読み取られてメモリにロードされます。次に、これを使用して暗号化キーを復号化します。

まず、Webサーバーとデータベースサーバーが同じシステムで、キーをどのように管理しますか?

キーはサーバー上のディレクトリに保存されます。更新または取り消しは通常、データベースプログラムを介して行われます。

2番目に、WebサーバーとDBサーバーが分離しているシステムでは、キーをどのように管理しますか?

キーはデータベースサーバー上にローカルに保存されます。より安全なオプションは、どちらのシナリオでもハードウェアセキュリティモジュール(HSM)を使用することです。これは、サーバーに接続され、サーバー上の制限されたフォルダーではなくキーを格納するために使用されるハードウェアデバイスです。

キーはアクセス許可が制限されたファイルですか?別のツール/ソフトウェアに保存されていますか?暗号化キーも暗号化されることがありますが、どこで役立つかは明確ではありません。

管理者アクセスを管理し、不正なログイン、サービスアカウントとしてのログイン、フォルダへのアクセス権が追加された新しいアカウントまたはグループなどを監視している限り、フォルダの制限は許容されます。上記のように、HSMは、保護しているデータと直面している脅威がそれを必要とする場合、より安全なオプションです。

通常、データベースはインスタンスキーまたはテーブルキーを作成し、これをマスターキーで暗号化します。マスターキーをさらに暗号化しても、メリットは最小限です。

11
Rakkhi

以前の回答ではいくつかの優れた情報が提供されていましたが、重大な設計上の欠陥があり、実際には気づかれていませんが、質問の暗黙の仮定の一部に起因しています。

次のような違いはありません。

  • 同じサーバー上のWebアプリとDB
  • 異なるサーバー上のWebアプリとDB
  • アプリケーションとデータベースの暗号化

設計は以下から開始する必要があります。

  • 暗号化/復号化キーにアクセスする必要があるのは誰ですか?

または、実際にはさらに正しい:

  • 誰がデータの機密性を保護する責任がありますか?

これは次のようになります。

  • どのような脅威から保護しようとしていますか?
    または
  • 誰がデータを読み取れないようにしようとしていますか?

これらの質問に基づいてのみ、適切に設計された暗号システムを設計できます。 (そして、@ D.W。が言及した暗号の妖精のほこりを防ぎます)。

したがって、いくつかのシナリオ例:

  • ユーザーは暗号化に責任があり、アプリ管理者でさえデータを見られないようにする必要があります
  • クライアントアプリケーションは、ユーザーを関与させることなく責任を負う必要がありますが、これはクライアント側で実行する必要があります(バックアッププログラムなど)。
  • Appserverは、ビジネスロジックの一部として、選択的データを適用可能かつ具体的に暗号化します(dbaでさえデータを見ることができません)。
  • データベースサーバーは、格納されたデータを自動的かつ透過的に暗号化する必要があります。 (これは、注意事項がありますが、dbファイル/物理ディスクの盗難からのみ保護します)。

簡単にするために、暗号化はサーバー側で行う必要があり、責任はサーバーにあり、エンドユーザー(および管理者)は暗号化に影響を与えないと仮定しましょう。

では、主な問題は、アプリケーションサーバーとデータベースサーバーのどちらで暗号化が行われるのでしょうか。 (実際にはそれほど単純ではなく、他のオプションがあります...)
これは、ほとんどのセキュリティ問題と同様に、トレードオフに戻ります。

  • 独自のキーを管理しますか、それともインフラストラクチャがこれを自動的に抽象化することを好みますか? (元の質問...以下の詳細...)
  • 悪意のある(または 無能 未経験)プログラマー?
  • 悪意のある管理者が心配ですか?
  • アプリケーションの不正使用を心配していますか?
  • 不正なSQLアクセスについて心配していますか?
  • 不正なファイルへの直接アクセスを心配していますか?
  • 物理ディスク/サーバーの盗難が心配ですか?

等々。 (上記の質問の一部は無関係であり、サーバーの暗号化では解決できないことに注意してください)。


ここで、上記に基づいて、アプリサーバーの暗号化とデータベースの暗号化の間で決定を下したと仮定します。
ウェブサーバーとデータベースが同じサーバー上にあるかどうかに関係なく、ここではほとんど効果がないことに注意してください。アプリが暗号化されている場合、「特別な」データをデータベースに送信するだけで、それ以外の場合は問題ありません。ただし、これは上記の脅威の議論に影響を及ぼします-一部の問題は設計によって廃止され、一部は強化されています...

  • Web /アプリケーションサーバーの暗号化
    • データの暗号化に使用する暗号化キー(EK)は、key暗号化キー(KEK)。
    • 暗号化されたEKは保護された場所に保存する必要があります-これはファイル、レジストリキーなど、何でも可能です-重要なのは、それへのアクセスをappserverのユーザーのみに制限することです(そして、おそらく管理者-下記を参照)。
    • KEKにも保護が必要です-これは少しトリッキーです。
      Windowsを使用している場合、 [〜#〜] dpapi [〜#〜] に簡単にアクセスできます。これにより、OSレベルのキー管理が提供されるため、OSを使用できますKEKを暗号化し、キーを透過的に管理します。 (舞台裏では、DPAPIは最終的に(USER_MODEで)ユーザーのパスワードを知ることに依存しているため、これが実際の既知の秘密の最終的な弱点ですが、他の誰も知ってはならない知っているそもそもサーバーのパスワードですよね?)
      別のオプションは、以下でさらに説明する外部デバイス/ HSMです。
    • もちろん、KEKにはアクセス制御も必要です。制限付きのACLなどです。
    • EKとKEKを分離する理由はいくつかあります。1つのキーで大量のデータを暗号化したくない場合。キーを交換する必要がある場合は、はるかに簡単になります(EKを新しいKEKで再暗号化するだけです)。 KEKでより強力で低速でより複雑な暗号化/ストレージを使用できます。 PCIに準拠する必要がある場合は、KEKに分割知識を実装できます。もっと。
    • EKとKEKの両方を暗号化せずに長期間保存しないでください。プラットフォームや言語によっては、これはたとえば、 .NETまたはJavaのStringオブジェクトに格納しないでください。代わりに、変更可能なバイト配列に格納し、常にできるだけ早く破棄するようにしてください。
    • 一部のフレームワークはさらに一歩進んで、特定の保護オブジェクトを提供します。例えば。 .NETでは、 System.Security.Cryptography.ProtectedMemory または System.Security.Cryptography.ProtectedData クラスを使用して、メモリ内でもキーを保護できます。
  • データベースの暗号化
    • データベースサーバーに暗号化を実行させると、これは非常に簡単になります。テーブル/フィールドは、そこに格納されているデータを自動的に暗号化するように構成され、キー管理は完全に透過的です(DBAではなくアプリケーションのPoVから)。など。
    • たとえば、OracleとMS SQL Serverはどちらも自動組み込み暗号化をサポートしています。 MSSQLの場合、キー管理は複雑ですが、上記で説明したものと似ています。簡略化:データベースに保存されているEKがあり、dbaはテーブルまたはフィールドの暗号化/復号化に使用するように構成できます。これは保護されたテーブルにあり、KEKで暗号化され、サーバーレベルのKEKで暗号化され、MSSQLのサービスアカウントでDPAPIを使用して暗号化されます。
    • または、MSSQLは非同期暗号化の使用もサポートしています。公開鍵と秘密鍵のペアの保存-これは特定のシナリオで役立ちます。
  • 3番目のオプション:外部暗号化ストレージ、または HSM(ハードウェアセキュリティモジュール) 。これは、共有ハードウェアアプライアンス、サーバー、またはハードウェアカードまたはドングルなどです。
    • これらのデバイスは、KEKなどの小さなデータを非常に安全に保護するように設計されています。
      ここでも、EKをKEKから分離するもう1つの理由-これにより、KEKを安全に管理しながら、EKで大量のデータを効率的に暗号化および復号化できます。
    • HSMは通常、特別なドライバーまたはAPIを介してアクセスされますが、これらもデータベースの暗号化にプラグインできる場合があります(製品などによって異なります)。
29
AviD