アプリ版:「スタンプのみでお礼する」機能のリリースについて

PHPでパスワードの登録でsaltを使用しようと考えているのですが、ネットで調べても自分の疑問に思っている事が出てきません。
パスワードにsaltという十分な長さ(40文字とか)の文字列を加え、それをmd5などでハッシュ化する・・・と言うことは分かりました。
しかしその実装方法が分かりません。

A.saltはランダム乱数でもいいし、セキュリティは低くなるが固定文字列でもいい。
B.saltは別ファイルに保管(一緒に保管と書いてあるのもありましたが)する。
、というような記事を見かけました。

で、自分はZendFrameworkのマニュアルに沿って考えたのですが、
データベーステーブルにpassword、saltカラムを作成する。
登録時、$_POST['ユーザの入力値']を(ハッシュ化する)passwordカラムに、saltはここでは単純にmt_rand(0,99)としてsaltカラムに登録、とした場合に認証時にはどのようにすればいいのでしょうか?

認証時にユーザの入力したパスワードとデータベースに格納したsaltを結合し、それをmd5()したものと、データベースに格納されているパスワードと同じく格納されたsaltを結合しそれをmd5()したものを比べる
・・・となるとパスワードさえ合って入ればいいので別にsaltは不要なような気がするのでこの実装法は間違っているのかなと思います。
そうではなく、登録時にユーザの入力したパスワードとデータベースに格納したsaltを結合し、それをmd5()したものをpasswordカラム又はsaltカラムに格納する・・・というのも正しいのかな?と思います。
データベースに侵入されればどちらもダメなので、何か別ファイルに保管するのかなとも思いましたが良く分かりません。

登録フォーム => ログインフォームにおいてのsaltの実装法を教えていただけないでしょうか?少し頭がぐちゃぐちゃになり、ちょっと文章がおかしい気もしますがすみません。

A 回答 (2件)

理想はユーザーごとのsaltの値を、別DBに保持するという方法かと思います。



> 登録時、$_POST['ユーザの入力値']を(ハッシュ化する)passwordカラムに、saltはここでは単純にmt_rand(0,99)としてsaltカラムに登録、とした場合に認証時にはどのようにすればいいのでしょうか?

同じテーブルにpassword, saltがあるんですよね?
で、認証の時って「パスワード」のみですか?

一般的なWEBシステムとかであればメルアドとパスワードとかですよね?
その前提でよいなら・・・ って話ですが。

1. saltの値 = メルアドの一部にする(n文字目から3文字抜き取るとか)。
2. なので初回登録時にsaltカラムにメルアドの一部が入る

認証時
3. メルアドとパスワードがパラメータとして送られてくるので、そのメルアドを元にレコードを取得。
 where メルアドの一部 = salt

4. データが増えてくれば複数件数SELECTされるので、SELECTされたデータを「パラメータ.パスワード + salt」でハッシュして、パスワードが一致するレコードを取得。

とかではダメですか?
もしくは、たいていの場合は、同じテーブル内に登録日時的なカラムがあったりすると思うので、そこを適当にいじくってsaltにするとかでもいいと思いますけど・・・

とゆーか、パスワード以外のカラムはこの場合、暗号化されていないって話ですか?
システムの目的にもよりますが、ある意味パスワードよりそれ以外の個人情報だとかの暗号化が難しかったりしますけどね・・・

他の方も回答されているとおり、saltの意義は同一パスワードが同じ値にハッシュされている状態を防ぐためです。
    • good
    • 0

>認証時にユーザの入力したパスワードとデータベースに格納したsaltを結合し、それをmd5()したものと、データベースに格納されているパスワードと同じく格納されたsaltを結合しそれをmd5()したものを比べる


>そうではなく、登録時にユーザの入力したパスワードとデータベースに格納したsaltを結合し、それをmd5()したものをpasswordカラム又はsaltカラムに格納する・・・というのも正しいのかな?と思います。

ちょっと日本語の違いがよくわかりません。大体あってる気がするのですが。

>saltは不要なような気がするので

DBが攻撃者に自由に見られる状態で、攻撃者に他人ユーザでのログインができるか?つまり、生パスワードが推測できるか?が問題ですよね。

ソルトなしだと、ハッシュ化されたパスワードと、あらかじめ作った「よく使われる語をハッシュ化した表」と照らし合わせるとその表にあればパスワードが判明します。

固定ソルトだと、悪意ユーザがパスワード 'abcd' で登録して、ハッシュ化された自分のパスワードと同じ文字列のユーザを探すと、そのユーザのパスワードも'abcd'だとわかります(同じパスワードだとハッシュ値も同じ)。
ただ、ユーザごとのソルトだとDBに持たざるを得ませんね(別DBにしてもいいのですが)。

実装としては、
(A) パスワード登録時
 ユーザが入力したパスワードと、ユーザごとに生成したソルトを連結して、ハッシュ化する。
 ハッシュ化パスワードと、ソルトをDBに保存する。生パスワードは捨てる。
(B) パスワード認証時
 ユーザが入力したパスワードと、DBにあるソルトを連結して、ハッシュ化する。
 ハッシュ結果と、DBにあるハッシュ化パスワードを比較して一致すればOK。

>データベースに侵入されればどちらもダメなので、

何がだめなんでしょう?
まあ、個々のユーザに対しての判明したソルトを使っての総当たりは可能ですね。これは防げません。ソルトは、上記の「あらかじめ作られた表」を使った解読を防ぐための技術です。
総当たりで解読されるまでの時間を稼ぐために、ハッシュを複数回行うということも行われるようです。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!