web-dev-qa-db-ja.com

私のアーキテクチャの欠陥を見つける:データの暗号化と回復のためのShamir's Secretの実装

これは長いものになります。

ここで重要なのは、データベース管理者がユーザーデータにアクセスできないプライバシー保護システムを構築することです。

直感的に、AESを使用して自分のパスワードでユーザーデータを暗号化し、ユーザー名をハッシュすることで、データベースにアクセスできる攻撃者が暗号化されたデータのパスワードをブルートフォースして情報を取得し、ブルートする必要があることをすぐに考えました。ユーザー名に、暗号化解除されたデータが誰であるかについてのアイデアを強制的に取得させます。

これは素晴らしいことですが、パスワードを忘れてしまうという問題につながります。パスワードを忘れた場合、正しいユーザー名または再設定用の電子メール(ハッシュも)を入力してパスワードをリセットできますが、データを取り戻すことはできません。 ProtonMail たとえば、あなたのデータはそこからも安全だと主張していますが、パスワードを忘れた場合はメールを復元できません。

それから秘密の共有について調べ始め、シャミールの秘密に出くわしました。したがって、私の質問は、私が提案するシステムは、難読化された(ハッシュされた)ユーザー名を使用してデータをプレーンテキストで単純に保存するよりもさらに悪いですか?

という事は承知しています:

  1. セキュリティには複雑さはありません
  2. このシステムは完全に完璧ではありません

しかし、私はそれがはるかに単純な解決策よりも優れているかどうかを知りたいだけですequallyハッカーにとって簡単/難しいが、harderデータベース管理者がデータから情報を収集するために、私にとってそれは価値があります。

データの暗号化+ややシンプルな回復を可能にする、私の心が現在思い付いた唯一のシステムであるため、ハッカーからデータを保護し、管理者。他の実装についても喜んで提案します。

さあ、行きます。

提案されたシステムは、Shamirの秘密を使用してk = 6およびn = 11でユーザーデータを暗号化するため、データを復号化するには6/11の部分が必要です。次に、ユーザー情報に「重み」が与えられ、暗号化された方法で比例した数のパーツを格納するために利用されます。このようなもの:

重量

  • ユーザー名:2
  • パスワード:4
  • メール:2
  • 秘密の質問1:1
  • 秘密の質問2:1
  • 名前+生年月日:1

これらの重みに基づいて、ユーザーのプライベートデータ(疑似コード)に対して次の処理が行われます。

SHAMIR(user_data, k=6, n=11)

これにより、長さ= 11のuint8配列のようなものが生成されます。その配列をpartsと呼びましょう。

次に、データベースは対称暗号化(AESとしましょう)を使用して、これらの部分を次のように格納します(結果の暗号文のみが格納されます)。

{
  username: AES(key=username, message=parts[0:2])
  password: AES(key=password, message=parts[2:6])
  email: AES(key=email, message=parts[6:8])
  seq1: AES(key=answer, message=parts[8:9])
  seq2: AES(key=answer, message=parts[9:10])
  id: AES(key=name+dob, message=parts[10:11])
}

次に、従来のユーザー名+パスワードまたは電子メール+パスワードでログインが行われ、データが正しく復号化された場合にユーザーが認証/ログインされます。どちらの組み合わせでも、データを復号化するのに十分な部分(6)にアクセスできます。ユーザーの観点からは、他のすべての場所と同じです。

次に、ユーザーは自分のパスワードを忘れます。さて、今、彼らはパスワードによって提供される4つの「ポイント」を収集するための別の方法を見つける必要があります。そのため、「パスワードを忘れた」をクリックすると、フォームにすべての入力可能なフィールドがポップアップ表示されます。データを復号化するには、ユーザー名または電子メールに加えてさらに4つの部分を収集するのに十分な量を入力する必要があります。例えば:

ユーザー名(2)+メール(2)+ seq1(1)+ namedob(1)= 6

(メール検証も実装できます)

したがって、ユーザーは6/11になります。サーバーはデータを復号化し、ユーザーは新しいパスワードを設定し、データは再暗号化され、すべてのフィールドが新しい部分で更新されます。定義上、パスワードを忘れたユーザーは、パスワードのリセットが完了した後、11ポイントのうち最低10ポイントを貯めます(提供した6ポイント+新しいパスワードの4ポイント)。したがって、1ポイント欠落する可能性があります。ユーザーがその最後のポイントを提供できない場合、新しいセキュリティの質問を追加するように求められ、その時点ですべてが正常に戻ります。

したがって、結論として:

秘密のすべての部分が同じ場所にあることは素晴らしいことではなく、エントロピーの低い秘密でAESを使用することは素晴らしいことではありません。

ただし、これはsomeセキュリティを追加する必要がありますか?データを取得するために、攻撃者は少なくともパスワードとユーザー名をブルートフォースする必要があります。または、パスワードをブルートフォースしない場合は、かなり他のデータをブルートフォースにする必要があります。決して完璧というわけではありませんが、標準よりデータプライバシーの方が優れていますよね。何が欠けていますか?それが完全に実装され、意図したとおりに機能すると仮定すると、今日の企業のデータ処理方法よりも悪いでしょうか?ほとんどの場合、データベース違反とは、データがすでにそこに存在していることを意味します。

最後に、これらの目的は他の方法で達成できますか?

それでおしまい。今まで読んだ方、ありがとうございます。私に気楽に行きなさい。

乾杯。

編集:私はここでUXについても少し考えています。パーツの格納に使用されるデータのエントロピーは確実に低くなりますが、ユーザーに高いエントロピーの「ランダムリカバリーコード」などを与えると、UXの観点から問題が発生します。

1
Yakko Majuri

シャミルの秘密の共有の考え方は、秘密の一部を知っている複数の当事者independentがお互いに存在するということです。あなたの場合のようにsingleパーティー、つまりあなたのサーバーがあります。これは、一部のファイルがパスワードで保護されていて、このファイルと一緒にパスワードを保持すると言っているようなものです。

シャミールの秘密共有を実装する場合は、ユーザーが新しいパスワードを提供した後、秘密の部分を生成してユーザーに提示し、ユーザーがこれらの部分を保持するように別の人に依頼する必要があります。あなたの場合、これは11人です。それ以外の場合は、Shamirの秘密の共有という言葉を使用しないでください。

セキュリティについて:多くの異なる側面を検討する必要があります。一つだけ指摘したいと思います。ケルクホフスの原理を考えてみてください。攻撃者がすべてのアルゴリズムを知っており、すべてのサーバーデータのコピーを持っていると想定する必要があります。それが私の意見では、あなたのスキームは単に曖昧であり、実際にはあなたが期待するセキュリティがないという理由です。

更新

  1. ケルコフスの原則によると、攻撃者はユーザー名、電子メール、および秘密の一部ではない同様の値を知っていることを期待する必要があります。

  2. シークレットは、ランダムであれば信頼できます。人の生活に関連するセキュリティの質問は、非常に限られた値のセットを持っているため、少数のエントロピーのみを提供します。エントロピーが小さいため、ランダムな値よりもはるかに簡単にブルートフォースを実行できます。

  3. セキュリティの質問を使用したい場合でも(弱点はあるものの)、直接使用してください。あなたが説明した他のすべての操作はセキュリティを追加しません。

セキュリティは、人が知っている(もちろん、エントロピーが高い)か、持っているか、あるかに基づいている必要があります。

AESを使用します。それはブルートフォースに耐性があります。しかし、あなたが提案するものは本質的に弱いです:総当たりの2つのセキュリティの質問、生年月日などははるかに簡単総当たりのAESよりもです。

魔法の解決策はありません。高度なセキュリティを提供し、ユーザーがパスワードを管理する必要があります。または、非常に低いセキュリティを提供し、ユーザーにパスワードを提供します。両方を行うことができます。ただし、2番目(低セキュリティ)を実装して、1番目(高セキュリティ)であることをユーザーに伝えないでください。

1
mentallurg