15

ユーザーがサインアップするPHPWebサイトを作成していますが、「電子メール確認」コードのベストプラクティスについて疑問に思っています。

新規ユーザーは自分のメールアドレスを確認する必要があります。これを行うには、コードを生成してユーザーにメールで送信します。このコードを使用して、アカウントをアクティブ化できます。このキーをデータベースに保存するのではなく、便利な小さな回避策を使用しています。コードは次の結果です。

md5("xxxxxxxxx".$username."xxxxxxxxxxx".$timestamp."xxxxxxxxx");

ここで、$timestampはユーザー作成時間を指します。全体的にはとても満足していましたが、それで考え始めました。これで十分安全ですか?そして、衝突の可能性はどうですか?また、パスワードリセットなどのコードを生成する必要があります。同様の方法を使用した場合、衝突により、あるユーザーが別のユーザーのパスワードを誤ってリセットする可能性があります。そして、それは良くありません。

では、これらのことをどのように行いますか?私の考えは次の形式の表でした:

codePK (int, a-I), userID (int), type (int), code (varchar 32), date (timestamp)

「type」は1、2、または3で、「アクティベーション」、「メール変更」、「パスワードリセット」を意味します。これはそれを行うための良い方法ですか?もっと良い方法はありますか?

上記と同様の方法を使用して、cronジョブを使用せずに2日以上経過したものを自動的に削除できますか?私のホスト(nearlyfreespeech.net)はそれらをサポートしていません。可能であれば、外部ホストでcronジョブを実行することは避けたいと思います。これは、物事を削除するスクリプトであるwgetです。これは、厄介な=Pです。

ありがとう!
マラ

更新:
明確にするために:このタスクを安全かつ安全に実行する唯一の方法は、データベースを使用することです。これは、元の関数が回避しようとしていたことです。私の質問は、テーブル(または複数のテーブル?)をどのように構成するかについてです。誰かが私がcodePKを廃止し、コードをPKにすることを提案しました。要するに、私の質問は、これはあなたがしていることですか?

4

5 に答える 5

10

私がこれらの種類のトリックを必要とするとき、それは通常2つの理由のうちの1つであり、両方ともあなたによって言及されています:

  1. ユーザーに送信される確認メールに使用されるキーとして
  2. パスワードリセットリンクに使用されるキーとして

もちろん、そのような構造の使用を検討する他の多くの機会があります。

まず第一に、あなたは常に隠されていてあなただけが知っているある種の塩を使うべきです。このソルトはユーザーごとに異なる必要があることに注意してください。塩は、たとえば、として計算できますsha256(something random)。このソルトは、ユーザー名とパスワード(ソルトでハッシュ化)とともにデータベースに保存する必要があります。

パスワードリセットリンクを送信するときに私が行うことは、別のソルトを作成することです(ユーザーに、ソルトでハッシュされたものへのアクセスを許可しないでください。彼は自分のパスワードを知っているので、ブルートフォースを使用すると、ソルトを把握できる可能性があります)。もう1つのソルトは、基本的にランダムな文字列のハッシュにすぎません(長さが問題であると述べたように、ここではmd5を使用することをお勧めします)。その後、データベースに保存します。

多くの場合、usersテーブルに列を追加するだけで済みます。ただし、これにはいくつかの問題もあります。主に、パスワードがリセットされるか、ユーザーがアクティブ化されると、データベースからキーが削除されるため、ほとんどの行の値がnullになり、他の問題が発生します。 。

これは本質的に次のように要約されます。

  • ユーザー固有のソルト(およびおそらくグローバルなシークレットソルト)を使用して、ユーザーのパスワードをハッシュします。
  • タイムスタンプなどのランダムまたは疑似ランダムソースの数をハッシュしてキーを生成しますmt_rand()。本当にランダムなものが必要な場合はrandom.orgもハッシュします。
  • パスワードリセットキー、アクティベーションキーなど、ユーザーがアクセスできるものをハッシュするために、グローバルソルトまたはユーザーに固有のソルトを使用しないでください。

私は決してセキュリティの専門家ではないことに注意してください。おそらく多くのことを忘れており、非常に悪い慣習について言及したかもしれません。ちょうど私の5セント;-)

于 2010-01-09T13:11:18.747 に答える
2

なぜユーザーのデータを認証キーの基礎として使用するのですか?

非アクティブ化されたデータをデータベースに保存していると思いますが、単にランダムキーである追加のレコード(おそらく、追加の操作を伴うmd5のuniqid)を追加して、それをチェックしてみませんか?

于 2010-01-09T12:28:08.977 に答える
1

インターネットでメソッドを公開するまでは、十分に安全でした。これは、隠すことによるセキュリティに依存していたためです。これはお勧めできません。

理想的には、自分だけが知っている秘密鍵を組み込んだ、ある種のキー付きハッシュ関数またはMACを使用する必要があります。

于 2010-01-09T12:25:49.810 に答える
0

コードフィールドを一意のインデックスにしてみませんか?それで、衝突は決してありませんか?

また、ユーザー入力からハッシュを作成してデータベースハッシュと照合する必要がない場合(電子メールの確認、パスワードのリセットなど)、ハッシュ本文にランダムな文字列を追加できます。 md5('xxx'.$username.'xxx'.time().'xxx'.rand())

于 2010-01-09T12:26:47.297 に答える
0

ユーザーにユーザー名コードを入力してもらい、衝突の問題を解消してみませんか?メールから取得するキーを引き続き要求しているため、セキュリティ面で何も失われることはありませんが、他のユーザーのパスワードをリセットできないようにします。

于 2010-01-09T12:29:27.447 に答える