web-dev-qa-db-ja.com

2つのソルトを使用-1つはパスワードとともに保存され、もう1つは別のテーブルのランダムな行に保存されます

ログインシステムが作成されていて、ユーザーのパスワードが次のようにハッシュされているとします。

Users.password = PBKDF2(salt1 + password + salt2)

その^演算の結果とsalt1は、同じテーブルに並べて格納されます(Usersなど)。

ただし、salt2は、UnorderedSaltsという別のテーブルのランダムな行に格納されます。

ユーザーがログインしようとすると、システムは次の情報を計算して資格情報をチェックします。

for (let i = 0; i < UnorderedSalts.length; i++)
  if (PBKDF2(Users.salt1 + input.password + UnorderedSalts[i]) === Users.password)
    return true; // Match found!

return false; // No matches were found

salt2saltおよびpasswordと同じ行に格納されないため、設定されているユーザー数に応じて、一致が見つかるまでに計算が何度も繰り返される可能性があります。

私の質問はこれです:

  • 潜在的な計算時間を増やすことにより、これはより安全なシステムを作るでしょうか?
  • これはパスワードのセキュリティを危険にさらしますか?
  • または、まったくメリットはありませんか?
1
Sasha

「潜在的な計算時間を増やす」ことは、セキュリティに良いことです。これがパスワードハッシュの基本です-遅いほうがいいです!

しかし、これはハッシュを遅くするために非常に不便な方法です!一部のパスワードでは、攻撃者が偶然に適切なソルトを試した場合、ラッキーになり、すばやくクラックされます。データベースファイル、ログなどがハッシュが作成された順序をリークするリスクがあり、どのソルトがどのアカウントにリンクされているかについての手がかりを与えます。サイトが成功し、突然100倍のユーザーを獲得した場合、計算するハッシュが100倍以上になると、サーバーが過負荷になります。混乱します。

PBKDF2、bcrypt、scryptを含むすべての最新の優れたパスワードハッシュ関数には、計算時間を構成するための組み込みメソッドが付属しています。これらのパラメーターは「コスト係数」と呼ばれます。代わりに使用してください!これにより、はるかにシンプルでクリーンなアーキテクチャが実現します。

4
Anders

メリットはまったくありません。

最も差し迫った質問に答えるために、2番目のソルトは、最初のソルトによってすでに提供されているものを超える利点を提供しません。多くても、ハッシュを目立たない場所に分割することで、あいまいさを介したセキュリティはごくわずかですが、攻撃者がシステムをより注意深く見ている間、あいまいさはせいぜい数分です。最悪の場合、あいまいなセキュリティにより、開発者と管理者は感じより安全になり、実装される可能性が低くなります効果的セキュリティ。

あいまいさによるセキュリティは カーホフの原理 に直接反します。これは、シャノンの再定式化を借りたいです:「敵はシステムを知っています」。

しかし、それだけでは何のメリットもありません。

単にパスワードをソルトおよびハッシュすることは、パスワードを保存する安全な方法とは見なされなくなりました。

コスト係数を調整可能なキーストレッチアルゴリズムを使用したい。

パスワード管理の現在の標準である NIST 800-63B にはPBKDF2とBALLOONがリストされていますが、セキュリティ専門家によって提案されている現在のキーストレッチアルゴリズムは、bcrypt、scrypt、またはArgon2に基づくKDFです。

PBKDF2は、利用可能な最新のライブラリがない場合でもピンチで確実に機能します-多くの単純な実装がハッシュを使用するため、使用しているライブラリが各ラウンドの最後に実際のHMACを生成していることを確認してください次のラウンドへの入力として結果自体。

1
Ghedipunk

結局のところ、UnorderedSalts.lengthの長さになります。短すぎる(おそらく10)場合は、セキュリティをほとんど追加しません。これが高すぎる場合は、ユーザーがログインしようとするたびに、検証するために大量のCPUパワーが必要になる状況にあります。

理想的には、攻撃者がシステムをブルートフォースで攻撃するのを困難にしながら、できるだけ少ない手順でユーザーとパスワードの組み合わせを認証できるようにする必要があります。

しかし、あなたの提案では、パスワードを検証するために0とUnorderedSalts.lengthの間のどこかが必要になるでしょう。これは、追加のコンピューティングだけでなく、これらの順序付けられていないソルトを取得するためのデータベースとの追加の往復を含むパフォーマンスの悪夢です。このアプローチのまったくの異常によって導入される複雑さは言うまでもありません。

パスワードを総当たり攻撃することがあなたの主要な脅威である場合、それに対処する方法は(前の回答で述べたように)難易度を微調整できるアルゴリズムを使用することです。難易度を上げるだけで、攻撃者を2倍、4倍、128倍も遅くすることができます。これはすべて、DBルックアップのない純粋なCPU計算です。

0
keithRozario