私は2で行きますが、塩を使用します。擬似コード:
SetPassword(user, password)
salt = RandomString()
hash = Hashfunction(salt+password)
StoreInDatabase(user, salt, hash)
CheckPassword(user, password)
(salt, hash) = GetFromDatabase(user)
if Hashfunction(salt+password) == hash
return "Success"
else
return "Login Failed"
ライブラリに実装されているよく知られたハッシュ関数 (MD5 や SHA-1 など) を使用することが重要です。自分で作成したり、本から実装しようとしたりしないでください。間違ってしまうリスクを冒す価値はありません。
@Brian R. Bondy: ソルトを使用する理由は、辞書攻撃をより困難にするためです。攻撃者は辞書をハッシュしてすべてのパスワードを試すことはできません。代わりに、彼女はソルト + 辞書を取得してハッシュする必要があります。ストレージ要件が明らかになります。最も一般的な 1000 個のパスワードの辞書があり、それらをハッシュすると、16 kB 程度が必要になりますが、ランダムな文字を 2 つ追加すると、62*62*16 kB ≈ 62 Mb になります。
私はOTPWについて良いことを聞いたことがありますが、使用したことはありません。