web-dev-qa-db-ja.com

PHPパスワードを忘れた場合の機能

私は小さなコミュニティWebサイトを持っていますが、何らかの忘れられたパスワード機能を実装する必要があります。私は現在、パスワードを MD5

「復号」を並べ替えてメールでユーザーに送信することは可能ですか、それともパスワードリセットページが必要ですか?

36
Liam

MD5ハッシュパスワードは元に戻せません。 (MD5はハッシュであり、実際には暗号化されていないため、微妙な違いがあります)。そしてyesパスワードの「リセット」プロセスを提供することは間違いありません(パスワードをメールで送信するだけではありません)。

安全なパスワードリセットのための高レベルのワークフローを提供するには...

  1. ユーザーがパスワードのリセットを求められたら、メールアドレスを入力させる
  2. そのメールアドレスが有効かどうかを示してはいけません(メールが送信されたことを伝えてください)。これは使いやすさを低下させるため、議論の余地があります(つまり、どのメールを登録したのかわからない)が、実際にサイトに登録されているメールに関する情報を収集しようとする人々にはあまり情報を提供しません。
  3. トークンを生成し(タイムスタンプをソルトでハッシュする場合があります)、ユーザーのレコードのデータベースに保存します。
  4. Httpsリセットページ(URL内のトークンとメールアドレス)へのリンクとともに、ユーザーにメールを送信します。
  5. トークンと電子メールアドレスを使用して、ユーザーを検証します。
  6. 新しいパスワードを選択して、古いパスワードを置き換えます。
  7. さらに、特定の時間枠(通常は24時間)後にトークンを期限切れにすることをお勧めします。
  8. 必要に応じて、「忘れた」試行が何回発生したかを記録し、人々が大量の電子メールを要求している場合は、より複雑な機能を実装します。
  9. 必要に応じて、リセットを要求している個人のIPアドレスを(別のテーブルに)記録します。そのIPからカウントを増やします。 10を超える場合は、今後の要求を無視してください。

ハッシュについてもう少し詳しく説明するには...

PHPのmd5()関数を使用してパスワードのような値をハッシュすると、最終的な値は、実行するサーバーに関係なく、そのパスワードに対して同じになります。 (つまり、ハッシュと暗号化の間にすぐにわかる違いが1つあります。秘密鍵と公開鍵は関係ありません)。

そのため、人々は Rainbow tables に対する脆弱性について言及していることがわかります。レインボーテーブルの非常に基本的な説明は... md5()ハッシュ値を取得するために、md5()が辞書の単語(弱いパスワード)をハッシュします。それらをデータベーステーブル(レインボーテーブル)に入れます。

これで、Webサイトのデータベースを危険にさらした場合、Rainbowテーブルに対してユーザーのハッシュされたパスワードを実行して、ハッシュを(本質的に)パスワードに「逆変換」できます。 (あなたは実際にハッシュを「逆にする」わけではありません...しかし、あなたはアイデアを得ます)。

そこで、パスワードを「塩漬け」するのがベストプラクティスです。これは、(ここでも非常に基本的な考え方です)ハッシュする前に、ユーザーのパスワードにランダムな値を追加することを意味します。これで、Rainbowテーブルがデータベースに対して実行されると、「password」のmd5()ハッシュが「password384746」とは異なるため、「逆転」しにくくなります。

Nice SO役に立つQ/Aです。 PHP passwords

134
Jared Cobb

この投稿によると、 フォームベースのWebサイト認証の決定的なガイド 、ステップ3および4について、保存している同じトークンを送信する必要があるかどうかはわかりません。

トークンを送信してからハッシュし、ハッシュされたトークンをDBに保存する必要があると思います。そうしないと、データベースが危険にさらされた場合、パスワードのリセットページにアクセスできます。

要約する :

$token = md5(microtime (TRUE)*100000);
$tokenToSendInMail = $token;
$tokenToStoreInDB = hash($token);

ここで、hashはハッシュアルゴリズムです。

9
Mansur Khan

いいえ、MD5は不可逆的です。パスワードをハッシュすることのポイントは、データベースにアクセスする攻撃者が全員のパスワードにアクセスできないようにすることです。

つまり、MD5(特に無塩MD5)は、一般的に レインボーテーブル を使用して攻撃できます。セキュリティのために、 bcrypt を使用することをお勧めします。

7
ceejayoz

あなたが行うための最善のことは、登録時に人々が自分のメールアドレスを提出することを要求することです。次に、忘れてしまった場合は、パスワードを忘れた場合に、パスワードをランダムな値にリセットしてパスワードをリセットします。この値は電子メールで送信されるため、アクセスしてパスワードをより思い出深いものに戻すことができます。このようにして、セキュリティを侵害する必要はありません。ユーザー名を送信するだけのリンクを用意することもできますが、セキュリティを高めるために、質問と回答または覚えやすいWordを用意する必要があります。

3
tom

パスワードを復号化することはできません。また、プレーンテキストを介してユーザーにパスワードを送信することも検討すべきではありません。 (これが私がサイトを二度と使用しないようにする一番の方法です。これは巨大なセキュリティホールです。)ユーザーのパスワード回復メールに送信される時間関連キーを含むリンクからトリガーされるパスワードリセットページを提供します;これがパスワード回復の最新技術です。

3
Paul Sonier

Marcus Reedが述べたように、2015/2016でPHP version> = 5.5を使用している場合、MD5を使用しないでください。password_hash()およびpassword_verify()は、コストを提供し、ハッシュを自動的にソルトする機能。

私は現在投票したりコメントしたりする能力を持っていないので、混乱を避けるために明確な声明を提供しています。

3
Chris

MD5は、一方向ハッシュにすることを目的としています。パスワードをリセットする必要があります。

組み込みのpassword_verifyおよびpassword_hashのphpを使用します。

2
Marcus Reed

取得パラメータとしてmd5と電子メールアドレスを受け入れるページを作成し、電子メールとmd5のパスワードをデータベースで検索します。 Jared Cobbのメモに続いて、それは正しい道を歩むはずです。私もいくつかの例を追加しました

例:送信するURL http://yourdomain.com/resetpassword.php?code=md5codesentviaemail

 $code = isset($_GET['code']) ? $_GET['code'] : '';
    $email = isset($_GET['email']) ? $_GET['email'] : '';
$checkPw = '';

    if(empty($code) || empty($email))
    {
     die();
    }
    $sqlQuery = 'SELECT * FROM users WHERE email = "'.$email.'";
//remember to check for sql injections
    //then get the results as an array, i use a database class eg $user

    if(!empty($user['password']))
    {
     $checkPw = md5($user['password']);
    }else
    {
     die();
    }

    if($checkPw !== $code)
    {
     die();
    }else
    {
    //display form for user to change password
    }

これは、ユーザーが有効なユーザーであることを知り、パスワードを変更するのに十分なはずです

2
Ryan

いいえ、解読できません。それが全体のアイデアです。

一時パスワードを送信し、パスワードをリセットする必要があります。

1
Neal

パスワードリセットページを実行する必要があります。 PHPでMD5を復号化する方法はありません。

1

MD5は一方向の関数です。解読できません。 SOパスワードリセットページが必要です。

1
Balanivash