人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

phpでパスワードをハッシュ化して安全にDBに格納したいと考えいてるのですが、ベストな方法が見つかりません。

phpのマニュアルの下記URLのアドバイスを見ると、crypt関数でBlowfishアルゴリズムでハッシュを作るのがベストな選択肢のようなのですが、
http://www.php.net/manual/ja/faq.passwords.php#faq.passwords.fasthash
それをどうやって実装していいのかがわからずに困っています。
マニュアルのcryptページのサンプルには
crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$')
このように例が記載されているのですが、saltは任意の文字列だと思われるのですが07?にあたる部分の「コストパラメーター」?を得る方法が分からずに困っております。

ちなみにPEARのCrypt_Blowfishというものを見つけたのですが、ググるとこれはどうも可逆暗号のようでパスワード文字列のように復号できると安全度が下がるようなものには使うべきではないのかと考えておりますが、あっておりますでしょうか。

質問を重ねて申し訳ありませんが、詳しい方にアドバイスをお願いできればと思います。
よろしくお願いいたします。

●質問者: n_maco2
●カテゴリ:コンピュータ ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● TransFreeBSD
●300ポイント ベストアンサー

幾つでもいいといえばいいのでは?
マニュアルをそのまま解釈すれば、04なら16回、08なら256回、31なら……21億回くらいハッシュ化を繰り返す、ということだと思います。
なので、数字を大きくすればするほど計算時間がかかってしまいます。
そしてそれが狙いです。なので、大きくできるなら大きくしておいた方が良いと思います。
多分(暗号理論は難解で以外な所に落とし穴あったりするので一応)

万が一、暗号化したファイルが流出した場合、ブルートフォースアタックで復号されてしまう危険性がありますが、ハッシュ化に時間がかかればかかるほど、探し当てる時間を長くできます。
例えば07の時、3日で探し当てるマシンがあったとします。すると08なら6日、10なら1ヶ月近く、14なら1年以上、20なら67年と、実質復号不能に持っていけます(ただし、将来的に計算アルゴリズムの改良による高速化とかハードの高速化を考慮しなければ)。
ただ、辞書攻撃などで陥落しない、本当に総当たりのブルートフォースアタックの場合という大前提がありますが。

http://net.tutsplus.com/tutorials/php/understanding-hash-functions-and-keeping-passwords-safe/
これの7番かな?


可逆暗号の場合、暗号化キーをどう扱うかという問題が発生します。
暗号化したデータと一緒に保存しては意味がありませんが、プログラムからはアクセス可能でなければなりません。
また、一旦復号出来た時は全てのパスワードが復号できる事になります。
ただ、例えばワンタイムパスワードを使用しようと思うと、一方向ハッシュは使えないのです。
なのでサーバに保存されたデータの流出を心配するか、ユーザの入力後の盗聴を心配するか、と言う話になると思います。

ただし、フィッシングとかソーシャルハック的攻撃に乗らないという前提での話になりますが。


n_maco2さんのコメント
ご回答いただきありがとうございます。コストパラメーターは自由なのですね。可能な限り高い数値にしておきたいと思います。暗号化キーの話もありがとうございます、参考になります。サーバーからの流出をどこまで疑うべきか、というのも悩ましいですね・・ ちなみに「salt の形式は、 "$2a$"、2 桁のコストパラメータ、"$"、そして文字 "./0-9A-Za-z" からなる 22 桁となります」とあるのですが、サンプルの crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$') これのsaltは33桁に見えるのですが、なぜだかわかりますでしょうか。22桁以上のものは切り捨てて使っていないのでしょうか・・

tdoiさんのコメント
適切なオフィシャルな説明は見つけてないですが、以下が参考になるかと。 http://stackoverflow.com/questions/2225720/why-does-crypt-blowfish-generate-the-same-hash-with-two-different-salts saltとして扱われるのは、「usesomesillystringforsalt$」であり、26文字です。 挙動を見る限り、22文字以上については打ち切られるようですね。

n_maco2さんのコメント
ご回答ありがとうございます。 私のほうでも文字数を増やして増加分がどうなるかのテストをしてみたりしてみたのですが、おっしゃるとおり文字数が大きいと無視されるようですね。大体疑問点が解消できました、ご協力いただきありがとうございます。 それにしてもオフィシャルの情報が不足?しているものを、パスワードという重要な機構に使うのは若干の不安を感じるのですが・・勉強不足と考えてこのままやるしかないですかねぇ・・テスト等慎重に進めてみたいと思います。 ありがとうございました
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ