2016-11-02 3 views
0

パスワードリセットまたは電子メールのアクティベーションのためのセキュアな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を使用する方が良いでしょう?

答えて

1

エンコーディング自体は、セキュリティに関して実際には何も変更されません。

すでに指摘したように、bin2hex()は、可能な文字列のベースが小さいため、同じバイト数の場合にはより長い文字列をbase64_encode()として返します。つまり、トークンの長さが指定されると、base64エンコーディングはより多くのエントロピーでトークンを生成し、したがってより適しています。

あなたのトークンが十分に強く(最小20文字のa..z、A..Z、0..9)、password_hashの代わりにソルトやキーストロークなしで単純なハッシュ関数(例SHA-256)を使用できます。この方法で、検索可能なハッシュをデータベースに作成できます。

少し前、私はsmall classを書いて、パスワードのリセットのために特定の長さのbase62トークンを生成しました。コードを見てみたいかもしれません。

+0

ありがとうございました。ユーザーに電子メールで送信されたハッシュを保存するのではなく、代わりにシリーズIDを保存して、ユーザーが指定したハッシュとpassword_hashを使用して暗号化されたハッシュを比較する方が安全だと思いましたか?なぜ検索可能なハッシュが必要なのでしょうか?タイミング攻撃のために安全ではないですか? – Niclas

+0

@Niclas - 良い質問。明確にするために、ユーザーにハッシュを送信せず、リンクに元のトークンが含まれている必要があります。サーバーアプリケーションがハッシュを再度計算してこのハッシュを検索するため、タイミング攻撃は機能しません。ハッシュは、2つの元のトークンの類似性について結論を出すことはできません。識別子の問題は、あなたがどこかにそれを格納しなければならないということです。あなたはそれをリンクと共に送る必要があります。これにより、(キーストレッチで保存された)短いトークンが可能になりますが、インクルードされた識別子のためにURLが大きくなります。 – martinstoeckli

+0

もう一度おねがいします。おそらく私の例では、トークントークンをハッシュと混同している可能性があります。少し混乱させてしまいます。私はあなたのクラスをチェックし、キーストレッチについてさらに読む予定です。私は長いトークンで問題はありません、そして、私は彼らがより安全だと感じていますが、おそらく128の文字base62は過剰ですか?私はHTMLの後ろにリセットリンクを隠していますが、誰かが普通のバージョンを読んでいて、URLの改行があっても問題があるかもしれません。しかし、私は、より少ないメールクライアントのためにセキュリティを犠牲にするべきですか? – Niclas

関連する問題