パスワードリセットまたは電子メールのアクティベーションのためのセキュアなURL安全ハッシュを生成するには、これらの機能のうち安全性の高いものはbin2hexまたはbase64_encodeです。bin2hex対ランダムハッシュトークンのbase64_encode?
1(これらのいずれかを使用して)トークンを生成:データベース内
$token = bin2hex(openssl_random_pseudo_bytes(32));
$token = strtr(base64_encode(openssl_random_pseudo_bytes(64)), "+/=", "XXX");
2.ストア:
$token_hash = password_hash($token, PASSWORD_BCRYPT);
INSERT INTO hash_table SET token_hash='$token_hash', series='X'
3.検証トークン:
SELECT token_hash FROM hash_table WHERE series='X'
if (password_verify($hash_from_url,$token_hash)) {
// Success
}
$ hash_from_urlが72文字を超えると、それ以上の違いはありません。
しかし、同じように長い文字列、つまり72文字の長さのランダムバイトを使用すると仮定した場合、bin2hexではなく16個の異なる文字を得るためにbase64を使用する方が良いでしょう?
ありがとうございました。ユーザーに電子メールで送信されたハッシュを保存するのではなく、代わりにシリーズIDを保存して、ユーザーが指定したハッシュとpassword_hashを使用して暗号化されたハッシュを比較する方が安全だと思いましたか?なぜ検索可能なハッシュが必要なのでしょうか?タイミング攻撃のために安全ではないですか? – Niclas
@Niclas - 良い質問。明確にするために、ユーザーにハッシュを送信せず、リンクに元のトークンが含まれている必要があります。サーバーアプリケーションがハッシュを再度計算してこのハッシュを検索するため、タイミング攻撃は機能しません。ハッシュは、2つの元のトークンの類似性について結論を出すことはできません。識別子の問題は、あなたがどこかにそれを格納しなければならないということです。あなたはそれをリンクと共に送る必要があります。これにより、(キーストレッチで保存された)短いトークンが可能になりますが、インクルードされた識別子のためにURLが大きくなります。 – martinstoeckli
もう一度おねがいします。おそらく私の例では、トークントークンをハッシュと混同している可能性があります。少し混乱させてしまいます。私はあなたのクラスをチェックし、キーストレッチについてさらに読む予定です。私は長いトークンで問題はありません、そして、私は彼らがより安全だと感じていますが、おそらく128の文字base62は過剰ですか?私はHTMLの後ろにリセットリンクを隠していますが、誰かが普通のバージョンを読んでいて、URLの改行があっても問題があるかもしれません。しかし、私は、より少ないメールクライアントのためにセキュリティを犠牲にするべきですか? – Niclas