私は多くの検索を行ったので読んでください、そしてこれは重複した質問ではないと信じています。
参考までに、これらの記事やその他の質問を既に読んだことがあります。
なぜ塩を保存しないのですか?私は塩を使わないことについて話しているのではありません。ユーザーがログインするたびにソルトを再生成し、ソルトをどこにも保存しないことについて話しています。
これが私が提案した理由です。私が所属しているグループである私たちは、より良いものに移動したいので、パスワードスキームを変更することにしました。グループの誰かは、塩を保存することが何らかの理由でセキュリティリスクであると感じたので、次のように決定しました。
「まあ、塩は保存しないでおきましょう。毎回再生してみましょう。」
これを聞いて、「なに?なぜ?」と思った。
返事として、「持っていないと使えないのでパスワードが保護されているパズルのピースです。」
「よし、毎回どのようにソルトを生成するのか?それは、ユーザーの存在の全体にわたって一定のままであり、決して変わらないものに基づく必要があるだろう」と私は言った。
「ユーザーのグローバルユーザー識別子ID(別名ユーザーIDまたはGUID)を使用しましょう」
「しかし、それは塩を本当にランダムで予測可能ではないのではないですか?」
「ランダムなコンポーネントを追加して混ぜ合わせます。」
「しかし……それでは、毎回それをどのように再生成するのか」
「まあ、ここにアルゴリズムがあります:」
ユーザー作成の場合:
認証の場合:
「しかし、なぜこのようにするのですか?」
「保護を追加するために、通常のパスワードスキームとは意図的に異なる何かをしたいのです。」 (私にはあいまいさによるセキュリティのように聞こえますが、私はこの部分を理解できます。これは、すでに安全であると考えられているアルゴリズムを使用する、正統でないアプローチです。
まあ、だから私の質問は:塩を保存せずに毎回再生成するメリットはありますか?もしそうなら、塩を再生するための合理的な方法は何でしょうか?そうでない場合、それは本当のセキュリティを追加しないためでしょうか(それはセキュリティシアターまたは不明瞭さによるセキュリティです)。
答えを簡単にするために、ソルトを毎回再生成し、データベースに保存しないことと、データベースに保存すること、およびこれが不明瞭またはセキュリティシアターによるセキュリティに分類されるかどうか、またはそれは有効なアプローチです。
こちらが私の見解ですが、皆様からのご意見もお待ちしております。
攻撃者がデータベースだけにアクセスする場合、塩は存在しないことがわかります。彼らはいくつかの単純なスキームを想定し、この想定に基づいてそれを攻撃します。攻撃の結果は得られません。彼らは頭を掻き始め、困惑しています。 (やや、パスワード保護の理想的なシナリオでしょ?)
SQLインジェクション攻撃はDBにはないのでソルトを取得しませんが、SQLインジェクションは過去のものですよね? :-)誰もがパラメータ化されたSQLを使用します。
パスワードハッシュを暗号化する必要性はそれほど高くありませんが、それでもなお良い方法です。上記のやや理想的なケースを想定しています。
とにかくデータベースに保存する一定の情報に基づく必要があるため、実際には無作為化されていません。これは実質的にソルトを保存するようなものです。
塩の再生成に使用されるユーザー属性の機密性に少し依存しています。
属性を「漏らす」と、塩の再生スキームのセキュリティが低下するかどうかはわかりません。そうだと思います。誰かが怒って会社を辞め、使用されているユーザー属性を開示するとします。攻撃者はソルト自体を再生成できるため、パスワードをより効果的に攻撃できます。
よく理解されたコードであり、コーディングとテストの魔法が少ない。
業界標準。私が集まる限り。多くの企業が公開されて、どのようなパスワードスキームを使用しているのかはわかりません。
攻撃者に見える。各パスワードをより効果的に攻撃できます。 (はい、作業係数にはpbkdf2またはbcryptまたはscryptを使用しますが、少なくとも時間がかかることがわかっている場合でも、少なくともどのように進めるかについての考えを持っています。)
あなたの質問への簡単な答えは、セキュリティに関しては創造的になることを試みないでください。 bcrypt または scrypt を使用してユーザーのパスワードをハッシュ化し、実際に解決する必要がある問題に進みます。これらのアルゴリズムのいずれかでハッシュされたパスワードコーパスは、予見可能な将来にそれらの(最も弱い)エントリのいくつか以上が壊れる可能性は低いです。
長い答えは、SHA-512で思い付く「魔法」は決定的であり、その場合、データベースを使用する攻撃者は同じ結果をもたらす可能性があるか、または非決定的であり、その場合、同じ量の生成を困難にするということです。あなたの攻撃者としての正しい塩。パスワードハッシュを確認するために、自分と攻撃者の両方にさらに多くの作業を強いる必要があるという点で、この戦術にはが意味があります。ソルトの「不明な」部分に16ビットのエントロピーがある場合、あなたと攻撃者の両方が単純にパスワードハッシュのこのコンポーネントをブルートフォースで試行する必要があります。平均すると、正しいものを発見するために32,768回試行されます。最近の [〜#〜] phc [〜#〜] のパスワードハッシュ候補の一部にはこのアプローチが組み込まれていますが、競争の勝者(Argon2)には組み込まれていないと思います。
それでも、それでも、自分でこれを実装しようとするべきではありません。暗号システムを構築または微調整した善意のアマチュアの死体が歴史に散らばっていますが、無意識のうちに壊滅的な欠陥をもたらしただけです。あなたやあなたの同僚がこれに免疫があることを期待する理由はありません。
特に過去のハッシュスキームと比較すると、既存のソリューションははるかに優れています。変更を加えると、使用する可能性が低いマージンによってセキュリティが向上します。深刻な弱点をもたらすリスクは、報酬よりもはるかに大きくなります。
データベースに保存されていない秘密のハッシュ成分は、「 pepper 」として知られています。 (それはグローバルでもユーザーごとでもかまいません。あなたのコショウはグローバルだと私は主張します。)そして、これがあなたがしていることです。
コショウの正当性は、誰かがすべてのソルトとハッシュを使用してユーザーデータベースをダンプした場合でも、コショウを持っていないということです。したがって、ハッシュは役に立たなくなります。これは、彼らがデータベースを読み取ることができただけの場合です。彼らもコードを読み取ることができれば、彼らもコショウを手にするでしょう。 -多層防御の手法です。
ソルトは、大量のパスワードハッシュに対するショットガン攻撃に反対しています。それらは未知である必要はなく、ハッシュごとに異なります。だからレインボーテーブルは役に立たない。
あなたのコンセプトはペッパーのみです。しかし、コショウに対して塩を使う必要はありません。あなたは両方を持つことができます。そして、あなたは塩なしで行くべきではありません。それでは、なぜ両方を持たないのですか?
塩はnotが秘密であることを意味します。 isは、少なくともデータベース内のユーザー間で一意であることを意味します。
この理由は、攻撃者がすべてのユーザーに対して同時にパスワードハッシュに対してブルートフォース攻撃を実行できないようにすることで既に言及されています。
ソルトをその目的を達成するためにユニークにするためにどの方法を使用するかは問題ではないので、それを明らかにすることは問題ではありません。ソルトの本当の目標は、再利用されたパスワードをユーザー全体のブルートフォース攻撃から保護することです。
再生されたソルトの実装を明らかにするために悪意のある従業員を必要としません。データベースにアカウントを持つ攻撃者は、自分のパスワードがすでにわかっています。そのため、ソルトがどの情報から生成されるかをすぐに把握できます。
したがって、ユーザーデータから再生成しても、実際には何も追加されません。ユーザーのパスワードが変更されたときに変更できるソルトを保存するのではありません。
私はそれを可能な限りシンプルに保ちます(セキュリティがそうであるように)。
ソルトはプライベートである必要はありません。 Saltsは、同じパスワードを持つ2人のユーザーに異なるパスワードハッシュを設定して、Rainbowテーブル攻撃から保護します。スキームを使用して非表示にすることは、このスキームを非公開にする必要があることを意味します(たとえば、ここで説明しましたが、採用するすべての開発者が、採用中または採用後に他の開発者と話し合う可能性があります)。
ユーザーIDをハッシュとして使用することは、ユーザーが自分のパスワードを以前のパスワードと同じに設定した場合、オブザーバーはこれが事実であることを確認できることを意味します。パスワードは変更されるたびにソルトを再生成する必要があります
アプリケーションのインスタンスが複数ある場合、デフォルトのユーザーは、各インスタンスで同じユーザー識別子を持っている可能性があります(たとえば、組み込みの管理者アカウント)。これにより、攻撃者は何が起こっているのかを理解するとユーザーIDを知ることができるため、このソルトに対してRainbowテーブルを作成することができます(私を信じて、時間がかかりません)。これが、暗号的に安全な乱数ジェネレータ(CSPRNG)によって生成される必要がある理由です。
"salt"はソルトではなく、パスワード生成スキーム内の一時的な変数です実際のソルトはユーザーの一意のIDで、ほとんど問題ありません塩の場合、塩はユニークでなければなりません。
"magic"と呼ぶものは、ほとんどの人が "pepper"と見なしますが、 "magic"を実際に秘密にしておく場合に限られます。 「あいまいなセキュリティ」を回避したい場合は、アルゴリズムをバージョン管理内に保持し、開発者がアクセスして公開することを許可する必要がありますが、実際の秘密の値をキーとして使用し、dbパスワードのように管理します。 1つの方法は、SHA256(uid, pepper)
を実行し、それを使用してパスワードをハッシュすることです。
パスワードにuidのみを使用する場合、saltは概念的にはグローバルではなくローカルでのみ一意です。理想的には、塩は世界的にユニークです。しかし、コショウを持っていると、(uid, pepper)
タプルのグローバルな一意性が得られるので、一意性に関して何をしても問題ありませんです。