web-dev-qa-db-ja.com

bcryptハッシュを無効なハッシュに置き換えると、パスワードが機能しなくなりますか?

データベース内の既存のbcryptハッシュを単純なダッシュ(-)。

A dash in a family of bcrypt hashes

古いパスワードが無効になり、他のパスワードと一致する有効なbcryptハッシュがないため、これは機能するようです。しかし、私は興味がありました、これは効果的ですか、それともセキュリティリスクを引き起こしますか?

これはパスワードを機能させない効果的な方法ですか、それともより大きなセキュリティリスクを引き起こしますか?

この特定の実装ではPHP password_verify 関数を使用していますが、一般的な実装に焦点を当てて回答をお願いします。上司の悪い習慣に焦点を当てないでください。また、ユーザーを非アクティブ/アクティブに設定するためのブールフィールド。

38
Markus Tenghamn

正当なログイン試行を禁止するという点では、問題ありません。非常に奇妙なハッシュ関数を使用している場合を除き、-にマッピングされる値はありません。また、データベースが盗まれた場合、欠落している値に対するブルートフォース攻撃を防ぎます。 bcryptの使用を考えると、ありそうもありませんでしたが、実装がパスワードを保存するためにひどい方法を使用している場合でも適用されます-プレーンテキスト以外のほとんどすべて)。

欠点としては、データベースが取得されると、他のアカウントのセキュリティがわずかに低下します-攻撃者がブルートフォースするレコードが少なくなります。彼らが注意を払っている場合、彼らはおそらく非アクティブとしてマークされているレコードを削除する必要がありますが、まだです。私は「少し」と言いました...

他のリスクは、比較のためにハッシュメソッドをバイパスできるアクセス方法がある場合(たとえば、何らかの理由で完全なハッシュを提供できるレガシーメソッドがある場合)です-その場合、アクティブをチェックしていない場合ステータスを慎重に確認してください。ダッシュを指定することでアクセスが許可される場合があります。この場合は、このアクセス方法を削除するのが理想的です。

39
Matthew

無効なパスワードハッシュ(通常は「*」)は、ハッシュする値を提供する方法がないため、パスワード認証を本当に無効にします。ただし、他の認証方法がある場合、無効なパスワードハッシュはアカウントを「非アクティブ化」しません。 SSH秘密鍵による。実際、これはキーのみの認証を適用する一般的な方法です。~user/.sshのssh公開キーと組み合わせた無効なパスワード。したがって、パスワード列の無効なハッシュは「アカウントが非アクティブ」ではなく、「パスワード認証がブロックされている」と解釈されるべきです。

パスワードアクセスが唯一の利用可能なパスである場合、無効なハッシュはソフトウェアサポートを必要としないため、おそらく明示的なフラグ設定よりも優れています。/etc/passwordactiveuser列があり、パスワードフィールドに有効なパスワードを残しながら使用した場合、一部のツール- mightactiveuserフィールドを無視します。

18
alexis

確かに大きな違いは、「非アクティブ」としてフラグが付けられているユーザーが引き続きログインできることですexceptサーバーはフラグをチェックし、試行を適切に処理します。また、ハッシュを「-」に変更すると、パスワードハッシュをどこかに保存しないと復元できませんが、フラグを削除すると、元の状態を効果的に復元できます。アプリケーションによっては、これが望ましい動作である場合とそうでない場合があります。

データベースへのアクセス権を持つ攻撃者は、このユーザーがログインできるとは想定されていないことを確認できるため、このアプローチによってセキュリティリスクが生じることはありません。正しく述べたように、bcryptハッシュは "-"に一致できません。形式だけでは一致しません。

Schroederがコメントで述べたように、これは悪い習慣ではありませんが、「非アクティブ」フラグを考慮に入れるようにログインメカニズムを変更せずにユーザーがログインできないようにするための一般的な概念(非アクティブなユーザーがログインしようとすると、暗黙的に拒否されます) )。

6
GxTruth

安全なハッシュの目的は、データベース内のパスワードを総当たりすることを困難にすることです。 「単純なハッシュ」のパスワードを解読したり推測したりすることが可能な場合は、アカウントのパスワードが危険にさらされています。

しかし、それだけではありません。単に誰かがクライアント側からパスワードを使用したり推測したりできないようにすることだけが目的であれば、問題なく機能します。この方法は長い間使用されてきました。ただし、バックエンドのパスワードエントリは脆弱化されています。他のコントロールがあり、アカウントの侵害のリスクと影響が低い場合、これは問題ありません。

5
schroeder

これは他の回答と同じ流れですが、最初に要点を繰り返します。これはユーザーを無効にする効果的な方法です他に方法がない限り。注意する例として:

ログインしているユーザーは、システムでどのように処理されますか?おそらく、ユーザーがシステムにログインすると、ログアウトするまで、おそらくCookie /セッションを使用してそれらを記憶しています。ユーザーがログインしたままであることを確認するために、セッションに何を保存しますか?最も重要なのは、ユーザーがログインしていて、パスワードハッシュが無効になっている場合はどうなりますか?パスワード自体をセッションに保存している場合、事実上すぐにログアウトされますが、パスワードをセッションに保存することはお勧めできません。パスワードハッシュをセッションに保存すると、それらもすぐにログアウトされます。ただし、セッションで、ユーザーがログインしているという事実と、ログインしているユーザーのIDを記録するだけの場合、ハッシュを無効にしても、現在ログインしているユーザーは自動的にログアウトされません。特に寿命の長いセッションがある場合は、問題だと思います。誰かのハッシュを非アクティブにして、1週間後にブラウザが開かれて、それでもログインしている場合はどうなりますか?これは、ユーザーに提供する「パスワードの更新」機能で古いパスワードを検証する必要がない場合はさらに悪くなります。その場合、ハッシュを非アクティブ化しても、すでにログインしている人はログインしたままで、パスワードを変更して有効なハッシュを回復し、アカウントを再アクティブ化できます。

APIキーにも注意してください。一部のシステム(Gitlabは、システムを変更する前にこれを行うためにいくつかの工夫をしました)は、APIアクセスに使用される長期間有効なAPIキーを持っています。 APIキーを知っているユーザーは、パスワードハッシュが変更されても、システムを引き続き使用できます。

多層防御の一般的な概念を考えると、システムに「正式な」非アクティブ化手順があることを個人的に投票します(通常、ユーザーテーブルには、通常の認証/許可フロー中にチェックされるステータス列があります)。結局のところ、非アクティブ化されたハッシュを使用するユーザーがシステムを引き続き使用できるようになる多くの警告が存在する可能性があります。もちろん、セキュリティは常に各エンティティのコスト/メリットのアプローチであるため、正式な非アクティブ化フラグを追加するのに時間がかかりすぎて、ここでの回答の「攻撃」手段のいずれにも該当しない場合は、おそらく大丈夫です。

5
Conor Mancone

はい、それはUnixの標準的な方法であり、古くからあります。

shadow(5) マニュアルページはあなたの質問に明確に答えます:

       If the password field contains some string that is not a valid
       result of crypt(3), for instance ! or *, the user will not be
       able to use a unix password to log in (but the user may log in
       the system by other means).

追加のトリックがあります。 passwd(1) にはオプション--lock

   -l, --lock
       Lock the password of the named account. This option disables a
       password by changing it to a value which matches no possible
       encrypted value (it adds a ´!´ at the beginning of the password).

       Note that this does not disable the account. The user may still
       be able to login using another authentication token (e.g. an SSH
       key). To disable the account, administrators should use usermod
       --expiredate 1 (this set the account's expire date to Jan 2,
       1970).

       Users with a locked password are not allowed to change their
       password.
3
Simon Richter

最初に注意すべきことは、「パスワードハッシュ」は単なるパスワードのハッシュではなく、ハッシュ自体だけでなく、使用されているハッシュスキームと必要なパラメータ( bcryptソルトとコストパラメータの場合)

したがって、無効な「パスワードハッシュ」が有効なパスワードにならないかどうかの質問への答えは、ハッシュ関数とは何の関係もありません。サポートコードの1つで有効なパスワードハッシュを表さない入力をチェックコードが処理する方法に要約されます。フォーマット。無効なハッシュを一致しないと見なすことを望む人もいますが、ドキュメントが明確ではないため、ソースを読む必要があります。

https://github.com/php/php-src/blob/master/ext/standard/password.c

https://github.com/php/php-src/blob/master/ext/standard/crypt.c

Phpのpassword_verifyのコードを読み取ると、最初に「php_password_determine_algo」が呼び出されることがわかります。パスワードが$ 2y $で始まる場合、「bcrypt」と見なされ、「$ argon2i $」で始まる場合、argon2と見なされます。それ以外の場合は、 「不明」と見なされます。

ハッシュが「bcrypt」または「不明」の場合は、php_cryptを呼び出してパスワードとハッシュを渡します。これにより、メソッドを使用して提供されたパスワードをハッシュし、既存のパスワードからソルトします。これは、内部実装、またはオペレーティングシステムのcrypt関数を呼び出す。無効な既存のハッシュが与えられると、内部コードは古い学校のDESにフォールバックするように見えますが、システムの実装が何をするかわかりません。

Password_verifyのunknown/bcryptセクションに戻ると、以下のいずれかに該当する場合、照合に失敗するようです。

  1. php_cryptはエラーを返します。
  2. php_cryptによって返されるハッシュの長さが、password_verifyに渡されるハッシュの長さと一致しません
  3. password_verifyに渡されるハッシュの長さが13文字未満
  4. php_cryptによって返されたハッシュの内容がpassword_verifyに渡されたハッシュの内容と一致しない

「-」のハッシュは、このリストの少なくともルール3によって拒否されます(ルール1または2も可能ですが、使用される暗号化実装の動作によって異なります)。

2
Peter Green