パスワードを一度ハッシュするのは安全ではありません
いいえ、複数のハッシュはそれほど安全ではありません。これらは、安全なパスワードの使用に不可欠な部分です。
ハッシュを繰り返すと、攻撃者が候補リスト内の各パスワードを試すのにかかる時間が長くなります。パスワードの攻撃にかかる時間を数時間から数年に簡単に増やすことができます。
単純な反復では不十分です
ハッシュ出力を入力にチェーンするだけでは、セキュリティには不十分です。反復は、パスワードのエントロピーを保持するアルゴリズムのコンテキストで実行する必要があります。幸いなことに、設計に自信を与えるのに十分な精査が行われたいくつかの公開されたアルゴリズムがあります。
PBKDF2のような優れた鍵導出アルゴリズムは、ハッシュの各ラウンドにパスワードを挿入し、ハッシュ出力での衝突に関する懸念を軽減します。PBKDF2はそのままパスワード認証に使用できます。Bcryptは、暗号化ステップで鍵導出に従います。そうすれば、鍵導出を元に戻すための高速な方法が発見された場合でも、攻撃者は既知平文攻撃を完了する必要があります。
パスワードを破る方法
保存されたパスワードは、オフライン攻撃から保護する必要があります。パスワードがソルトされていない場合、事前に計算された辞書攻撃(たとえば、レインボーテーブルを使用)でパスワードが破られる可能性があります。それ以外の場合、攻撃者は時間をかけて各パスワードのハッシュを計算し、保存されているハッシュと一致するかどうかを確認する必要があります。
すべてのパスワードが同じように使用されるとは限りません。攻撃者はすべての短いパスワードを徹底的に検索する可能性がありますが、ブルートフォース攻撃の成功の可能性は、キャラクターが追加されるたびに急激に低下することを知っています。代わりに、最も可能性の高いパスワードの順序付きリストを使用します。それらは「password123」で始まり、使用頻度の低いパスワードに進みます。
攻撃者リストが長く、100億人の候補者がいるとしましょう。また、デスクトップシステムが1秒あたり100万のハッシュを計算できると仮定します。攻撃者は、1回の反復のみが使用された場合、リスト全体を3時間未満でテストできます。ただし、2000回の反復を使用した場合、その期間はほぼ8か月になります。より高度な攻撃者(たとえば、GPUの能力を利用できるプログラムをダウンロードできる攻撃者)を打ち負かすには、より多くの反復が必要です。
いくらで十分ですか?
使用する反復回数は、セキュリティとユーザーエクスペリエンスの間のトレードオフです。攻撃者が使用できる特殊なハードウェアは安価ですが、それでも1秒あたり数億回の反復を実行できます。攻撃者のシステムのパフォーマンスによって、何度も繰り返された場合にパスワードを破るのにかかる時間が決まります。ただし、アプリケーションでこの特殊なハードウェアを使用することはほとんどありません。ユーザーを悪化させることなく実行できる反復回数は、システムによって異なります。
おそらく、認証中にユーザーにさらに3/4秒ほど待たせることができます。ターゲットプラットフォームのプロファイルを作成し、可能な限り多くの反復を使用します。私がテストしたプラットフォーム(モバイルデバイスの1人のユーザー、またはサーバープラットフォームの多くのユーザー)は、60,000〜120,000回の反復でPBKDF2を快適にサポートでき、コスト係数が12または13のbcryptをサポートできます。
その他の背景
ハッシュにおけるソルトと反復の役割に関する信頼できる情報については、PKCS#5をお読みください。PBKDF2はパスワードから暗号化キーを生成するためのものでしたが、パスワード認証の一方向ハッシュとしてはうまく機能します。bcryptの各反復は、SHA-2ハッシュよりもコストがかかるため、使用する反復を少なくすることができますが、考え方は同じです。Bcryptはまた、派生キーを使用して既知の平文を暗号化することにより、ほとんどのPBKDF2ベースのソリューションを超えた一歩を踏み出しました。結果の暗号文は、いくつかのメタデータとともに「ハッシュ」として保存されます。ただし、PBKDF2で同じことをするのを妨げるものは何もありません。
このトピックについて私が書いた他の回答は次のとおりです。