web-dev-qa-db-ja.com

HTML5 localStorageおよび暗号化された機密データ

ウェブサイトに機密データを記憶させる方法を探していますが、実際にはサーバー側に保存していません。そして私はそれを行うためにHTML5 localStorageを見ていました。これが私が見ている計画です。

  1. ユーザーは機密データをフォームに入力して送信します。
  2. サーバーは、AES-256を介してデータを暗号化し、秘密のソース管理で保持される強力なキーを使用します。
  3. サーバーは応答し、レンダリングされたページに暗号化されたデータを提供します。
  4. ページはJavaScriptを実行して暗号化されたデータをlocalStorageに保存します

後で...

  1. ユーザーがJavaScriptを使用してlocalStorageから暗号化されたデータをフェッチするページにアクセスし、サーバーに送信します。
  2. サーバーは暗号化されたデータを復号化し、そのリクエストの機密情報にアクセスします。

私の考えでは、クライアントまたはサーバーのいずれかが危険にさらされ、事態は安全なままです。クライアントが危険にさらされている場合、ハッカーは解読するキーのない暗号化された文字列のみを読み取ることができます。サーバーデータベースが危険にさらされている場合、データは単にそこに格納されないため、ハッカーがアクセスすることはできません。

(明らかに、一部のタイプのサーバーハッキングでは、機密データが最初から入ってくるときにそれを読み取ることができますが、そのようなハッキングはクライアントがデータを保存しているかどうかにかかわらず機能するため、この説明には当てはまりません。仕事、私は単にここでデータストレージがどちらかの側で危険にさらされることについて話している)

しかし、私はセキュリティの専門家ではないので、自分の計画に穴があるかどうか疑問に思っていますか?ここで見逃している目立ったセキュリティの脆弱性はありますか?

3
Alex Wayne

これには2つの大きな問題があります。

  1. データを特定のブラウザのインス​​トールに関連付けます。したがって、誰かが別の場所からログインしてアクセスすることはできません。または、同じマシン上の別のブラウザでもかまいません。これは、ほとんどのWebアプリの目的に反します。また、公共のマシンはどうですか?機密データは暗号化されていますが、一般にアクセス可能なマシンに保存します。

  2. サーバーに送り返されるデータの検証には、非常に注意が必要です。それがあなたのコントロールの外にあると、あなたはそれについて何も仮定できません。

そしてその後、サーバーはハッキングされる可能性があります(データが危険にさらされていなくても).

6
GrandmasterB

ウェブサイトに機密データを記憶させる方法を探していますが、実際にはサーバー側に保存していません。

サーバーを使用して暗号化されたデータを保存します。localStorageを使用する理由はありません。クライアント側でパスフレーズを使用してデータを暗号化することをお勧めします。最も弱いリンクがパスフレーズのクライアント側で入力しているため、このメソッドはクライアントをまったく保護しません。

基本的に必要なものは次のとおりです。

  • ユーザーには機密データがあります:「キャンディを盗んだ」.
  • ユーザーがパスフレーズを入力します。
  • JavaScriptはパスフレーズを消費し、遅いハッシュを計算します(たとえば、scrypt、適切なキーストレッチアルゴリズムなど)。
  • JavaScriptはハッシュを使用して機密データを暗号化します。
  • JavaScriptは、指定された低速ハッシュから別のハッシュを計算します。
  • JavaScriptは、ダブルハッシュと暗号化されたデータをサーバーに送信します。
  • サーバーは受信したダブルハッシュのハッシュを計算します。
  • サーバーは、トリプルハッシュと暗号化されたデータを保存します。

これでブレークがあり、すべてのcookie/localStorage/sessionStorageがクリアされます。

  • ユーザーが戻ってきて、もう一度パスフレーズを入力します。
  • 再度ダブルハッシュを計算し、別のハッシュを計算して既存のトリプルハッシュとの照合を試みるサーバーに確認します。このようにして、ユーザーは安全に認証され、暗号化されたデータが返されます。
  • 次に、そのトリプルハッシュに属する暗号化されたデータが返され、パスフレーズの単一のハッシュがデータの復号化に使用されます。

データがどこに保存されていても、パスフレーズなしでは誰も機密データにアクセスできません。ユーザーのみがパスフレーズを知っている必要があります。必要に応じて、ユーザーは復号化されたデータをいつでもサーバーと共有できます。ただし、サーバーが危険にさらされていることを懸念している場合(そうであるようです)、機密データの処理をクライアント側で行います。

パスフレーズはユーザーの頭にあり、暗号化されたデータはサーバーに保存されるため、機密データをハッキングする唯一の方法は、クライアントのキーボードを傍受するか、パスフレーズをブルートフォースで強制することです。

したがって、いくつかの重要な仮定があります。

  • すべてのハッシュでソルトを使用しました。
  • キーストレッチハッシュは将来性があり、十分に低速です。
  • パスフレーズには十分なエントロピーがあります(そのため、推測/強制することは困難です)。
  • サーバーとの接続はHTTPSです。
  • パスフレーズとシングルハッシュは使用後に破棄され、グローバルにアクセス可能なスコープでは使用されません。パスフレーズを入力することが最も弱いリンクであることに注意してください。

次に例を示します。

# CLIENT
singlehash = keystretcher(passphrase + salt1)
ciphertext = encrypt("I stole candy", singlehash)
doublehash = fasthash(singlehash + salt2)

         |
         |
       HTTPS(ciphertext, doublehash)
         |
        \ /
         '

# SERVER
triplehash = fasthash(doublehash + salt3)
store(ciphertext, triplehash)

そして、クライアントが戻ってきたとき:

# CLIENT
singlehash = keystretcher(passphrase + salt1)
doublehash = fasthash(singlehash + salt2)

         |
         |
       HTTPS(doublehash)
         |
        \ /
         '

# SERVER
ciphertext = fetch(fasthash(doublehash + salt3))

         |
         |
       HTTPS(ciphertext)
         |
        \ /
         '

# CLIENT
decrypt(ciphertext, singlehash) == "I stole candy"
4
Yeti