1

パスワードを保存するとき、ソルトは秘密にする必要はなく、すべてのハッシュを一意に保つことが唯一の目的であると言われています。パスワードの長さを制限することは良い習慣ではないとも言われていますが、次の例を検討してください。

ハッシュ化する前に、ユーザー入力を最大 100 にトリミングし、ソルトとして追加の文字を追加することにより、プレーン テキスト バージョンが内部的に常に 128 文字であることを確認します。

したがって、ユーザーが 20 文字を入力すると、108 文字のランダムな文字がソルトとして追加されます。ユーザーが 100 を入力すると、28 が追加されます。ポイントは、プレーン テキスト バージョンの長さは 128 文字にする必要があるということです。コードでは、次のようになります。

$salt   = generate_salt($pass); // length varies as explained above
$hash   = hash('sha512', $pass.$salt);

このようにして、ハッシュ前の「プレーン テキスト」は常に 128 文字になります。

$hash をサーバー A に保存し、$salt をサーバー B に保存します。

ここで、攻撃者がハッシュ DB (サーバー A) へのアクセスを取得し、ハッシュを元に戻すことに成功したと仮定しましょう。彼には良さそうに見えますが、128 文字であるため、彼が見る平文バージョン (または逆ハッシュ) はまだハッシュのように見えます。彼はソルトを知らないので、元のパスワードを決して知りません。

追加の課題として、SHA512 が 128 文字を生成するという事実により、(既に述べたように) プレーン テキスト バージョンはハッシュのように見えるため、プレーン テキスト バージョンに到達したかどうかも確信が持てません。一見すると、彼はそれが反復バージョンであると考えるかもしれません。そうであれば、彼はおそらく無期限に反復を続けるでしょう。

ハッシュの反転が発生した場合、ソルトの秘密を保持するとセキュリティが強化され、プレーンテキストの長さを均一に保つと難読化のレイヤーが追加されるため、このアプローチに問題はありますか?

注: これはもちろん、アプリに複数のログイン失敗の検出/防止機能があることを前提としています。

4

3 に答える 3

3

まず第一に、自分が何をしているのか本当によくわかっていない限り、独自の暗号システムを発明しないでください。

既存のもの ( PBKDF2bcryptまたは scrypt など) を使用してください。これは、単純なソルト付きハッシュよりも利点があります。これは、より多くの CPU 時間 (3 つすべて) やメモリ (後者の 2 つ) を使用し、並列化のコストが高くなるためです。

ハッシュのソルトは、ブルート フォース攻撃からではなく、レインボー テーブルからのみ保護します!.

攻撃者がハッシュを元に戻すことに成功$pass.$saltした場合、攻撃者は(したがって、パスワード) の知識を得ることができます。

ソルトの目的は、安価なレインボー テーブルの作成を回避することです。つまり、攻撃者は、考えられるすべてのパスワードのハッシュを計算してデータベースと比較するだけでなく、さまざまなソルトごとにこれを行う必要があります。

ソルトを秘密にしておくことには、攻撃者が考えられるすべてのパスワードに対して考えられるすべてのソルトを試す必要があるため、攻撃をさらに高価にするという理論上の利点があります。

ただし、実際には、サーバー A にアクセスできるようになると、おそらくサーバー B にアクセスできるようになります。

何かがハッシュのように見える場合、おそらく重要ではありません。サーバーが侵害されると、攻撃者はおそらくどのような難読化技術が使用されているかを突き止めることができます。

補足: SHA-51264 ASCII 文字である 512 ビットの出力を生成します。

于 2012-04-28T21:06:36.377 に答える
1

このアプローチの最初の問題は、独自の暗号化コードを実装していることです。これはほとんどの場合、悪い考えです。暗号化は難しく、微妙な方法で非常に簡単に失敗します。他の人々は、暗号化プリミティブとその上に構築されたサービスを実装するために多くの時間と労力を費やしてきたので、あなたがする必要はありません. しかし、議論のために、本当にこれを行う必要があると仮定しましょう:-)。

2 番目のことは、ユーザーの入力を切り捨てていることです。つまり、貴重なエントロピーを捨てており、何のメリットもありません。最大 128 文字分のソルトを生成する準備が整いました。常にこれを行って、それらを (パスワードと一緒に) ハッシュにフィードしないのはなぜですか? 切り捨てることで何を得ますか?私が見る唯一の答えは、おそらく元のパスワードは「128文字なのでハッシュのように見える」ということですが、それは単に真実ではありません。ソルトされたパスワードは実際のパスワード データで始まりますが、これは通常、ハッシュとは非常に似ています。

三つ目は、あなたの心を正しく読み取れなかった私の失敗かもしれませんが、あなたのこれらの塩がどこから来ているのかはっきりしていないということです. あなたはそれらを「ランダム」と表現し、攻撃者はそれらを知らないと言います。しかし、認証システムはどのようにそれらを取得するのでしょうか? それらはパスワードから派生しているように見えますが、その場合、salting-plus-hashing はわずかに複雑なハッシュ関数であり、実際には何も得られません。

あなたが明らかに拒否した(またはおそらく遭遇しなかった)一般原則は次のとおりです。すべてのソースコードを含め、攻撃者が知っている可能性のあるすべてのものを知っているという前提で暗号化システムを常に設計してください。これは良い原則であり、拒否するべきではありません。小さな「難読化の追加レイヤー」に依存しても、うまくいきません。最悪の場合、(システムを複雑にすることで) バグが発生しやすくなり、偽りの安心感を誘発します。

于 2012-04-28T21:08:45.250 に答える
0

Salt は秘密である必要はなく、唯一の目的はすべてのハッシュを一意に保つことです

また、テーブル全体に対して 1 つのハッシュを試すのではなく、すべてのハッシュ + ソルトの組み合わせに対して行ごとに試行する必要があるため、ハッシュのテーブルをブルート フォースするのが「遅く」なります (' select * from passwords where hash = ' xxx' ')

ソルトを秘密にしておくことでセキュリティが強化され、プレーンテキストの長さを均一に保つことで難読化のレイヤーが追加されることは間違いありませんか?

「逆ハッシュ」がハッシュのように見えるという事実は、本当の追加のセキュリティを追加しません (実際には、あいまいさによる単なるセキュリティです)。Web サーバーはサーバー Aサーバー B (ユーザーとパスワードの組み合わせを認証するため) に接続する必要があるため、そのサーバーが危険にさらされると、すべての希望が失われます。

興味のある記事は、Jeff Atwood によるこのブログ投稿です。(編集:間違ったコーディングホラーリンクを投稿)

于 2012-04-28T21:05:04.757 に答える