4

どうやら、ユーザー名とパスワードをハッシュして Cookie として保存し、無害化された Cookie データでログインすることは、ユーザー (または私のサイトの安全性) にとって十分ではないようです。

このアプローチで十分ですか?

登録手順:

$salt= date('U');
$username= hash('sha256', $salt. $_POST['username']);
$password= hash('sha256', $salt. $_POST['password']);
$token = hash('sha256', $salt. (rand(1,10000000000000000000000000000000000000000000)));

手動でログインするには、ユーザーはユーザー名とパスワードを入力します。これはハッシュを通過して照合されます。

ログインに成功すると、ユーザーに対して 2 つのクックが作成されます。1 つはハッシュされていないユーザー名を保持し、もう 1 つはハッシュされたトークンを保持します。

ユーザーがアクセスすると、Cookie が設定されている場合、サイトはユーザー名をハッシュし、これら 2 つの値を使用してログインします。

このアプローチの利点は、ユーザーのパスワードをコンピューターのどこにも保存しないことです。誰かがトークンをクラックして自分のアカウントにアクセスできるかもしれませんが、少なくともユーザーのパスワードを危険にさらすことはありませんでした...

MySQLreal_escape文字列と Cookieに回答した人は、ユーザー データを Cookie に保存するのは間違っていると言っています。これは問題をそらしますか?

4

4 に答える 4

5

暗号化されたバージョンであっても、なぜパスワードを保存する必要があるのでしょうか? あなたのサイトは、バックエンドで HTTP 基本認証などを行うサードパーティ API にアクセスしていますか?

残念ながら、あなたの質問に対する決定的な答えはありません。「適切」とは、人によって意味が異なります。また、秘密の質問については、「十分に適切」または「十分に安全」であることが可能かどうかはわかりません。とはいえ、ログインとパスワードのセキュリティを処理する方法は次のとおりです。私のデータベースのusersテーブルには、ログイン関連の列が 3 つあります。

  1. ユーザー名
  2. パスワードハッシュ

username列はプレーン テキストです。salt列は、ランダムに選択された英数字の 64 文字の文字列です。列は、値とpasswordHash連結されたユーザーのパスワードsaltであり、不可逆的にハッシュされます。ハッシュにはsha256を使用しています。sha256 が生成するので、salt は 64 文字です。ハッシュされた文字列に十分な可変性を生み出すために、少なくともハッシュと同じくらい長いソルト値を持つことは良いことです。

ユーザーがログイン フォームを送信すると、ユーザー名のデータベース クエリを実行します。ユーザー名が見つからない場合は、「無効なユーザー名および/またはパスワード」エラーをユーザーに表示します。ユーザー名が見つかったら、salt とパスワードを連結し、ハッシュして、passwordHash値と等しいかどうかを確認します。そうでない場合、ユーザーにはまったく同じエラーが表示されます。

ユーザー名が間違っているか、パスワードが間違っているか、またはその両方であるかに関係なく、まったく同じエラー メッセージを表示することをお勧めします。ハッカーに与える手がかりは少ないほどよい。また、ユーザーがパスワードを変更するたびに、新しいパスワードも提供しsaltます。その時点でこれを行うのは非常に簡単で、塩の値を少し新鮮に保ちます.

ユーザーごとに異なるソルトを持つこのシステムは、動的ソルティングと呼ばれます。これにより、ハッカーがレインボー テーブルを使用してユーザーのパスワードをリバース エンジニアリングしようとすると、作業が非常に複雑になります。言うまでもなく、パスワードを不可逆的にハッシュ化された形式で保存すると、たとえデータベースや PHP コードにアクセスできたとしても、ユーザーのパスワードを誰かが特定できないようにするのに非常に役立ちます。

これは、ユーザーがパスワードを忘れた場合、それを取得する方法がないことも意味します。代わりに、再ログインしたらすぐにパスワードを変更するように強く勧めるとともに、ランダムに決定された新しい値にリセットするようにシステムを記述します。次にログインが成功したときにこれを強制するようにシステムを作成することもできます。

パスワードは 8 文字以上にする必要があります。理想的には、数字と特殊文字も含める必要がありますが、これを必須にするかどうかはまだ決めていません。多分私はすべきです!

ブルート フォース攻撃から保護するために、過去 10 分間に失敗したすべてのログインを追跡しています。私はそれらを IP アドレスごとに追跡します。ログインに 3 回失敗すると、システムはこのsleep()機能を使用して、それ以降のログイン試行への応答を遅らせます。次のようなコード ブロックを使用します。

$delay = ($failedAttempts - 3);
if ($delay > 0) {
    sleep($delay);
}

IMHO これは、何度も失敗した後にユーザーをアカウントからロックアウトするよりもはるかに優れています。これにより、カスタマー サポートからの問い合わせの数が減り、自分のパスワードを思い出せない正当なユーザーにとってはより安全になります。ブルートフォース攻撃は、何らかの効率を得るために毎秒多くの試行を行う必要がありn = xます。

ログイン セッションは、PHP セッションで追跡されます。session_start()サイトのすべてのページが読み込まれたときに呼び出します。header.php(共通ファイルがあれば、これは非常に簡単です。) これにより、 $_SESSION変数が使用可能になります。ユーザーが正常にログインすると、これを使用して、ユーザーがログインしていることを知るためにサイトが必要とする情報を保存できます。通常、ユーザー ID、ユーザー名、およびサイト固有のその他の詳細を使用します。ただし、パスワードやそのハッシュはここには含めません。サーバーに保存されているユーザーのセッション データにハッカーが何らかの方法で侵入したとしても、この方法でユーザーのパスワードを見つけることはできません。

ログアウトは、次の 2 つのいずれかが発生した場合に発生します。1) ユーザーのセッション Cookie が削除された場合 (ブラウザーのキャッシュをクリアするか、場合によってはブラウザー ウィンドウを閉じるだけである場合もあります)、または 2) サーバーがセッション データを削除した場合。session_destroy()ユーザーがサイトの「ログアウト」ボタンを押したときに呼び出すことで、後者を強制的に実行できます。そうしないと、一定期間後にセッションが自動的に期限切れになる可能性があります。session.gc_*これには、でパラメーターを微調整することが含まれる場合がありますphp.ini

最初のログイン フェーズの後にユーザーのパスワードを絶対に知っておく必要がある場合は、パスワードを に保存できます$_SESSION。これは、サイトで SSL 接続が必要であり、SSL 接続なしではサイトが機能しないように設定している場合にのみ実行してください。このようにしてパスワードは暗号化され、パケット スニッフィングから保護されます。ただし、ハッカーがサーバーのセッション データにアクセスした場合、セキュリティ上のリスクがあることを知っておいてください。

于 2012-07-03T02:32:27.770 に答える
1

あなたの塩は十分にランダムではありません。

これに関する問題は、リプレイ攻撃です。悪意のある人物が、サイトにアクセスする途中でユーザーの Cookie を収集するとします。彼 (悪者) が同じ値を送信して、本物のユーザーであるかのように侵入するのを妨げるものは何ですか?

ユーザーデータを Cookie に保存するのは良くありません。ユーザーのブラウザーの Cookie に 1 つのランダムな 64 ビット数値を保存することで、問題を解決できる可能性があります。アプリケーションの認証データベースには、乱数と、ユーザー名、Cookie が最初に有効になった時刻、有効期限が切れる時刻、および場合によってはブラウザー情報と IP アドレス情報などの顕著なプロパティを記録します。

Cookie が送信されると、Cookie を送信したときと同じブラウザーから送信されたように見えることを検証します。

これをベストプラクティス、またはユーザーを「確実に」再度識別するために必要なことについては確認していません。しかし、ランダムデータには意味のあるものは何も含まれていないため、悪者がそれをキャプチャしても世界の終わりではありません. キャプチャされた Cookie の有効性は制限されており、適切な詳細をキャプチャした場合、悪者はユーザーの環境をかなり正確にシミュレートする必要があります。

于 2012-07-03T01:23:14.150 に答える
0

私が Wi-Fi ホットスポットのようなオープン ネットワーク上の悪意のあるユーザーであり、ユーザーのアカウントの 1 つを制御したいと考えた場合、次のアプローチを試すことができます。自分を守る。

  • date('U') をソルトとして使用していることを (SO の投稿から) 知っているので、各テストの前に既知のソルトを追加して、辞書を使用してパスワードをクラックしようとします。
  • 暗号化されていないトラフィックを許可している場合、トラフィックを盗聴してトークンをハイジャックします。願わくば、あなたのサイトが私の電子メール アドレスを変更し、パスワードを電子メールで送信する方法を提供してくれることを願っています。
  • ファイルにアクセスできる場合は、ファイルからトークンを抽出して直接使用します。

考えられるもう 1 つのアプローチは、フィールドをシリアル化し、その文字列を暗号化し、それを base64 でエンコードしたメッセージを Cookie に保存することです。また、既存のソルトに大きな乱雑な文字列を追加します。

于 2012-07-03T01:46:28.783 に答える
0

ユーザー名をハッシュ化する理由 それは秘密ではありません。とにかく、ログイン資格情報を検索するには、ハッシュされていない (または少なくともソルトされていない) ユーザー名が必要になります。

また、openssl_random_pseudo_bytes() 代わりにrand(). それ以外は、基本的な考え方は問題ないようです。

于 2012-07-03T01:32:59.250 に答える