パスワードのハッシュ値を保管するときのsaltの作り方

タイトルは作り方ですが、手順はありません。 教えていただいた徳丸さんに感謝。
17
flat/京山和将@昼夢堂 @flat_ff

パスワードハッシュ値のsaltって低品質の乱数由来でもいいんだろうか?ユーザーごとに分けろって話はあるけど、精度はあまり問題にならない?見つけた範囲では、/dev/urandomつかってるものから、平文パスのmd5を使ってるものまでさまざま。

2011-01-13 10:48:12
徳丸 浩 @ockeghem

@flat_ff そもそも乱数である必要がないと思います。平文パスのmd5は良くないと思いますが

2011-01-13 10:53:36
flat/京山和将@昼夢堂 @flat_ff

@ockeghem 今のところの要件は、「ユーザーごとに異なる」ことと「推測できないこと」で合ってますか?それに合致させるのに乱数が使いやすいというだけってことですよね。

2011-01-13 11:01:09
flat/京山和将@昼夢堂 @flat_ff

@ockeghem 安全なsaltの作り方というほどの基準はないにしろ、危険な(やってはいけない)saltの作り方ってありそうですね。どんな例があるでしょうか?何らかのユーザー情報を元にしたり、時刻を元にした例も見ました。

2011-01-13 11:02:38
徳丸 浩 @ockeghem

@flat_ff Saltを乱数にした場合データベースに保存しないといけないので、予測不可能性をSaltに求めても意味がありません。ということで、乱数にする必要もありません。最低限の要件は、短くないことと、ユーザ毎に違うことです。パスワードを元にしたSaltは後者を満たしません

2011-01-13 11:09:30
flat/京山和将@昼夢堂 @flat_ff

@ockeghem 乱数については了解です。細かい違いですが、同じユーザーがパスワードを変えるときに、saltは同じでいいのでしょうか?変えても同じsaltなら、一度変えて戻したときにハッシュ値も同じになりますよね。これは問題ないですか?

2011-01-13 11:23:42
徳丸 浩 @ockeghem

@flat_ff 特に気にしなくてもよいと思っています。というか、変える根拠が見あたりません。そういう、なんとなく○○すると良い、××するべきだ、という主張が多くてイライラしますね

2011-01-13 11:31:49
flat/京山和将@昼夢堂 @flat_ff

@ockeghem ちょっとひっかかったのは、IDとsaltのペアがわかっていれば、事前にハッシュテーブルを用意できるかなと思いました。人数分用意する必要はありますが、ターゲットが絞れるなら充分脅威かも、と。

2011-01-13 11:43:11
flat/京山和将@昼夢堂 @flat_ff

@ockeghem 「○○すべき」というなら根拠出したり責任持ったりして欲しいですよね。でも、そう言わないと「何をやればいいのかわからない」と言われて何もしてもらえないことも多々あります…

2011-01-13 11:45:10
徳丸 浩 @ockeghem

@flat_ff まぁ書いてて困ることがあるのも確かで、根拠が怪しい時は「パスワード入力欄は通例マスク表示する」とか、「パスワードの定期的変更は一般的なガイドラインとして認知されている」などと書きますね。

2011-01-13 11:52:05
松村 成裕@ウェブマーケティングエンジニア @PrimaryText

@flat_ff とりあえずハッシュになってれば、そこまで気にしないという実装、多いと思う。ウチ、銀行じゃないし、って逃げ道。

2011-01-13 12:44:47
flat/京山和将@昼夢堂 @flat_ff

さっきのハッシュsaltの話って、あとでまとめたほうがいいのかな。実例とかもうちょっと欲しい感じ。

2011-01-13 16:14:03
flat/京山和将@昼夢堂 @flat_ff

【まとめ】短いsaltは使わない。別のユーザーに同じsaltを使わない。saltに乱数を使う必要はない。平文パスのハッシュ値をsaltにしない。

2011-01-13 16:28:19
flat/京山和将@昼夢堂 @flat_ff

---------- その後考えてみたこと ----------

2011-01-22 08:57:20
flat/京山和将@昼夢堂 @flat_ff

UNIXのpasswdの実装がランダムに見えるsaltなので、擬似乱数を使ってる実装が多い。(実際はUNIX TIME+PIDを使っている) 同じユーザーの同じパスワードでも毎回ハッシュ値が変わる。その妥当性はどうあれ、広く使われている方法に合わせるのは悪い手法ではないと思う。

2011-01-22 08:29:18
flat/京山和将@昼夢堂 @flat_ff

ユーザーIDをsaltとした場合、毎回saltが変わる場合に比べてメリットはあるのか?ひとつ思いついたのは、「パスワード再利用禁止」にたいする優位性。

2011-01-22 08:32:04
flat/京山和将@昼夢堂 @flat_ff

同じユーザーが同じパスワードを使う限り、再設定しても同じハッシュ値になる。なので、「同じパスワードを一定期間再設定禁止とする」ポリシーに対してハッシュ値のみで実現できる。

2011-01-22 08:35:25
flat/京山和将@昼夢堂 @flat_ff

何らかの理由でsaltを変えたいときが出るかもしれない。そのときはIDごと変えないといけないけど、そういう場合が出るかは不明。IDとは別にsaltを記録して、単なるパスワード変更ではsaltを変えないという運用もありそう。

2011-01-22 08:40:40
flat/京山和将@昼夢堂 @flat_ff

IDをそのままsaltにする場合は、一意性を保ったまま十分な長さを確保しないといけない。「IDには使えないけどsaltには使える文字」で埋めるか、IDのハッシュ値を使う方法がありそう。

2011-01-22 08:46:59

微妙な違和感が残っていたのを形にできたので、質問してみました。

flat/京山和将@昼夢堂 @flat_ff

@ockeghem wasbook p.327 51-001のパスワードのハッシュ化について質問です。運用中にハッシュアルゴリズム(あるいはストレッチ回数)を変えることになった場合、単にソースを変更しただけでは認証ができません。どういう対応が望ましいでしょうか?

2011-06-15 18:52:38
flat/京山和将@昼夢堂 @flat_ff

@ockeghem ちょっと考えた方法は、ログイン認証時に新旧両方のアルゴリズムでハッシュ値を出して比較します。新ハッシュ値と一致ならそのまま認証OKとし、旧ハッシュ値と一致なら新ハッシュ値で置換してOK。両方と不一致ならNGです。問題ないでしょうか?

2011-06-15 18:52:56
徳丸 浩 @ockeghem

@flat_ff それでも大きな問題はないと思いますが、ハッシュ値にアルゴリズムを示す番号を追加しておくと良いです。1:XXXX だったらバージョン1の方法、2:XXXXだったらバージョン2の方法という具合に。後から追加する場合は、XXXX → 2:XXXX という具合

2011-06-15 19:04:12
flat/京山和将@昼夢堂 @flat_ff

@ockeghem UNIXのpasswdで見る$1$っぽい(ただしsaltを含まない)イメージですね。ありがとうございました。

2011-06-15 19:09:32

もし他のシチュエーションがあっても、バージョン付けで実装すれば多分対応できそうです。
パスワード変更時にももちろんハッシュのバージョンは変えられるのですが、ログイン時にもこっそり上げられるというのは地味にいいポイントなのかなと思います。