web-dev-qa-db-ja.com

ユーザーごとにデータを暗号化する方法のどちらがより安全ですか?

ちょっとした思考実験として、ユーザーごとのキーを使用して、ユーザーのデータ(たとえば、Webページのフォームから)がサーバーに保存され、暗号化されるWebアプリケーションを設計する方法を考えてきました。 。復号化されたデータは、ユーザーが再度ログインすると、Webページのフォームに表示されます。

私は2つの潜在的なアプローチを考え出し、それぞれの長所と短所を特定しようとしましたが、他の人の考えを知りたい-私は certain私はすべての可能な攻撃について考えたことはありません。


3つのアプローチすべてで一貫している私の架空のシステムのいくつかのプロパティを次に示します。

  1. すべてがSSL経由で発生します。
  2. SSLを通過するCookieはすべて安全とマークされます。
  3. 暗号化するデータ:プレーンテキストで構成されるWebページ上の単一のフォームフィールド
  4. データはN桁のPINで暗号化されます
  5. N桁PINはサーバー上のDBに保存されます(暗号化または暗号化)

  6. N桁PINは、パスワード導出関数を介して渡され、256ビットの暗号化キーを生成します

  7. AES-256-CBCモード、ランダムIVを使用して暗号化されたデータ。 Encrypt-then-MACアプローチを使用して署名(たとえば、何らかの形式の認証済み暗号化)。 HMACキーは、N桁のPINから取得されます。


オプション1:サーバー側のセッションオブジェクトに一時的に格納されたキーを使用してサーバーで暗号化する:

  1. ユーザーはPINを使用してログインします。
    • サーバーはPIN DBのダイジェストに対して認証します。
    • サーバーはPINパスワード導出関数を介して256ビットのキーを生成します。
    • サーバーはサーバー側のセッションオブジェクトにキーを格納します(&はRedisまたはmemcachedに永続化されます)。
    • サーバーは、ユーザーがデータを入力するためのフォームをレンダリングします(&セッションIDを含むCookieをクライアントに送信します)。
  2. ユーザーがフォームにデータを入力し、サーバーに送信します。
    • サーバーはサーバー側セッションオブジェクトのキーを使用してデータを暗号化し、暗号化されたデータに署名します。
    • サーバーは、署名され暗号化されたデータをDBに保存します。
  3. ユーザーがログアウトする/セッションが期限切れになる
    • キーはセッションからワイプされ、永続キャッシュからワイプされます。

短所
-サーバー側の攻撃では、攻撃者はanyの暗号化キーをユーザーに取得し、復号化することができます彼らのデータ。

長所
-キーはサーバーに一時的にのみ存在します。ユーザーがログアウトすると、永続化された暗号化データは(比較的)DBで安全になります。
-クライアント側の攻撃では、攻撃者はそれほど攻撃を受けません。Cookie内のセッションIDのみです。
-サーバー側の攻撃では、攻撃者はログインしているユーザーのみを攻撃できます-しかし、どれだけのプロなのかはわかりません。
-サーバーサイドの攻撃では、攻撃者はユーザーの未加工のPINを取得することはできません。


オプション2:サーバーで暗号化し、キーをクライアントに送信する暗号化されたcookieに保存:

  1. ユーザーはPINでログインします。
    • サーバーはPIN DBのダイジェストに対して認証します。
    • サーバーはPINパスワード導出関数を介して256ビットのキーを生成します。
    • サーバーは暗号化されたcookieにキーを格納します。
    • サーバーは、ユーザーがデータを入力するためのフォームをレンダリングします(セッションIDと暗号化されたキーを含むCookieをクライアントに送信します)。
  2. ユーザーがフォームにデータを入力し、サーバーに送信します。
    • サーバーは暗号化されたCookieからキーを抽出します。
    • サーバーはクライアントのCookieのキーを使用してデータを暗号化し、暗号化されたデータに署名します。
    • サーバーは、署名され暗号化されたデータをDBに保存します。
  3. ユーザーがログアウトする/セッションが期限切れになる
    • Cookieはクライアントのマシンでローカルに削除されます

短所
-クライアントでは、攻撃者は暗号化キーを持っています-しかし、それだけが彼らが持っているものです。暗号化および署名されたデータや固有のIVはありません。
-つまり、(おそらくPINを使用して)ログインしている場合は、すでに復号化されたデータを見ています。暗号化されたキーを持っているだけでは何も購入できません。暗号化キーは他のユーザーのデータに対しては機能しません(明らかに同じPINを使用している場合を除きますが、攻撃者がそれを知る方法はありません)。

長所
-キーはサーバーに永続化されず、一時的な瞬間にのみメモリに存在します。永続的な暗号化データは、(比較的)DBで安全です。
-クライアント側の攻撃では、攻撃者はユーザーの未加工のPINを取得することはできません。
-サーバーサイドの攻撃では、攻撃者はユーザーの未加工のPINを取得することはできません。
-サーバー側の攻撃では、攻撃者は他のユーザーの暗号化キーを入手することはできません。
-攻撃者が何らかのダメージを与えるには、攻撃に成功する必要があります両方サーバーとクライアントであり、ダメージは1人のユーザーに限定されます。


セキュリティには常にトレードオフがあり、完全に安全なものはないことを完全に理解しています。ただし、攻撃者がサーバー(たとえば、咳、NSA)の内部に侵入できると想定すると、暗号化キーが均一であるサーバー側のアプローチのように感じます一時的に一時的にのみ保存されるのは危険です。

直感に反して、オプション2はmore secureです。

私は正しい/間違っていますか?どちらの方法も悪い考え(TM)ですか?もしそうなら、考慮すべきいくつかの代替アプローチは何ですか?

2
Rob

これは、質問というより、議論のポイントのように感じられます。これは、あなたの質問に対する明確な答えはなく、単に推測しているためです。

質問に答える最良の方法は、リスク評価を行うことです。これはあなたのリスク選好度を含み、処理される情報を収集して保存するのに最も適した方法をより適切に示します。

リスク評価には、このアプリケーションのコンテキストも含まれますが、質問には含まれません。コンテキスト、つまり情報の価値を理解していなければ、最善の行動方針は推測にすぎません。

1
NRCocker

ここでは、妥協後のセキュリティを提供する方法で、アプリケーションサーバー上のユーザーの暗号化キーを保護することが重要です。

妥協後のセキュリティとは何ですか?

シームレスなキーローテーション:

  • アプリの実行中にキーをローテーションできます
  • キーはプロアクティブに、またはデータ侵害があった場合にローテーションできます

盗まれたデータの無効化

  • 暗号化サーバーの協力なしにデータを復号化することはできず、データベース内の盗まれたデータは役に立たなくなります

ゼロ知識証明

  • 暗号サービスは、すべての操作がその秘密鍵を使用して実行されたことを証明します

オンラインとオフラインの両方の攻撃に耐える

  • ユーザーごとの厳格なレート制限
  • パスワードの試行を行うには、アプリケーションと暗号化サービスの両方の秘密鍵が必要です

ソース

また、(ユーザーパスワードのように機能する)PINを保護し、パスワード強化暗号化(PHE)を使用する必要があります。

0
Dmytro