質問: phpのハッシュ関数に関する疑問です。第二版php逆引きレシピの574pで、可能な組み合わせをすべて試すブルートフォース攻撃から安全性を保つためにpasword_hash()という関数は、ソルトという 無作為に作られたデータをパスワードに付与する、と記述してあります。つまり、計算量が多くなるから、不正な接続や攻撃に時間がかかるようになるということです。 しかし下記のページでは、総当たりに攻撃を行うブルートフォース攻撃から身を守るためにソルトは役に立たない、効果がないと書いてあります。 http://securityblog.jp/words/6452.html いったいどちらが正しいのでしょうか。 不正な攻撃や接続を行う人は、相当な知識を持っていらっしゃると思うので、計算量が増えた程度では、安全性は保てないという認識で良いのでしょうか。
回答: プルートフォースアタックは予測を行わずに可能性のある候補を総当りで試す方法ですが、この要素を踏襲しても目的や状況によって手法は複数に分かれます。 攻撃者に対象のユーザID以外何も情報が無い場合、単純にあるユーザのパスワードをプルートフォースアタックで破ろうとするなら、ログイン画面でパスワードの候補を片っ端から試していく手法が考えられます。 パスワードが英語小文字で8文字と決まっているなら26^8≒2088億回程試せば、相当運が悪くても正解が見つかります。この方法であれば、試すのは暗号化前の文字列ですから(ログイン画面に打ち込んだ文字列をPHPがハッシュ化してDBのハッシュ済みの値と比較する)どのように変化されていようとも試行回数に代わりはありません。なのでソルトをつけて暗号化しても(この方法での解析の)難易度は変わりません。 でも考えてみてください。ログイン画面から何億回もパスワードを変更しながらトライを繰り返すと相当時間が必要になります(1回辺りの処理時間はサービスサーバの処理能力や間の回線によって制限をうけます)し、その間に管理者に不自然なログが発見され対策されると思います。 では目的のユーザの暗号化済みのパスワードを入手していたらどうでしょう? これなら攻撃者が自前の設備を使って自由に解析作業を進める事ができます。 全く意味不明の文字列からどのようにして(総当りを使って)元の文字列を割り出すのかちょっと想像できませんが、単純にユーザの入力した文字列をハッシュ化したものより、プログラムがソルトを付け足した文字列がハッシュ化されている場合のほうが難易度が増すように思いませんか?