質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.20%

password_hash()の安全性について

解決済

回答 4

投稿

  • 評価
  • クリップ 20
  • VIEW 5,589

gammaaex

score 8

 質問

PHPにおいてpassword_hash()はなぜ安全なのでしょうか?
暗号アルゴリズム、ストレッチング回数、ソルトなどパスワードの解析における情報は全てそのハッシュに収められています。従って、password_verify()単独で真偽判定が可能であり、それは本当に便利なのですが、その分、ハッシュが漏洩した際に十分安全ではないと言えるのではないでしょうか?

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+30

パスワードの保存にハッシュ値を用いるのは、「もっと良い方法がない」からというのが単純化した理由です。
たとえば、暗号鍵を安全に保存でき、外部に漏洩しないことが確実であるならば、ハッシュ値よりも暗号化して保存した方が確実です。
しかし、そもそもパスワードを保護する理由というのは、なんらかの理由でパスワード情報が漏洩した後の保護をしたいわけなので、パスワード情報は漏洩するが鍵は漏洩しないというシナリオは描きにくいわけです。絶対にできないわけでもありませんが、ハードウェアセキュリティモジュール(HSM)を使用するような高価な方法となりますし、サーバーに侵入されているという前提では、HSMとて絶対とまでは言えません。
このため、暗号鍵のような秘密情報を安全に保存できるという前提をさわやかにあきらめた方法が、pashword_hash等で採用されている方法で、これが現在の主流です。
まず、ハッシュ値というのは、平文からハッシュ値を求めるのはある程度高速にできるが、ハッシュ値から平文に戻す手段はありません。ただし、パスワードの場合は、総当りで求める方法があり、password_veryしながら順にしらべていけば、理論的にはいつかは平文パスワードが分かります。
しかし、その「いつか」が100年後であれば、実質的には問題ないわけです。もちろん、1000年後とか1万年後であれば、さらに安全です。
なので、password_hashで用いられているアルゴリズムは、「計算に時間が掛かる」という性質を持っています。単に計算量が多いと言うだけでは不十分です。ハッシュアルゴリズムは比較的単純なのでGPUによる高速計算ができる場合が多いのですが、パスワード保存用のハッシュアルゴリズムには、GPUによる高速計算がやりにくいような工夫がされています。

一方、ハッシュ値の計算に秘密情報を混ぜることもできますが、著名なアプリケーション等ではあまり見かけない方法です…といいつつ、私が本を書いた時にはこの方法を採用しました。当時はまだ password_hash関数がなかったからそうしましたが、今は、password_hashを使うことをお勧めします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+7

端的に言えば、パスワードを照合する以上は他の方法でも「暗号アルゴリズム、ストレッチング回数、ソルトなどパスワードの解析における情報」はソースコード上に(明示的であるか暗黙的であるかはともかく)表現されていて、それを隠すことによるセキュリティ向上はさしたるものがないからです。

AESにしてもBcryptにしても、(軍事レベルのものを除けば)暗号アルゴリズムは基本的に公開され、「ケルクホフスの原理」として知られるように、「暗号方式は、秘密鍵以外の全てが公知になったとして、なお安全であるべきである」ように作られています(弱点が見つかったものは淘汰されていきます)。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

+3

ハッシュが漏洩した際に十分安全ではないと言えるのではないでしょうか?

ハッシュが漏洩した場合は大変危険です。ヒントを与えてしまっていることは確かなので。
ただ、ハッシュが漏洩したということは、一般的には DB にアクセス可能な状態になっていると考えられます。
その場合、パスワードのハッシュ値とストレッチング回数、ソルトを分離して保存しておいたとしても全て流出してしまっている可能性が高いです。
アルゴリズムに関しては、想定されるアルゴリズム数がそれほどないので漏れても漏れなくても誤差の範囲かと。

つまり、password_hash() で作られるハッシュは、暗号アルゴリズム、ストレッチング回数、ソルトなどパスワードの検証に必要な情報をすべて持っていますが、それぞれを分離して保存した場合とそれほどセキュリティ精度は変わらないと考えられます。

ちなみに、password_hash() が推奨されるのは、色々お作法の必要であった「暗号学的ハッシュ関数」をラップし、お手軽に使用できるようにしたためです。お作法を間違えると、途端にスカスカになる「暗号学的ハッシュ関数」を使用するよりは password_hash() を使用することで、ケアレスミスを防ぐって観点で推奨されています。
別に password_hash() のほうが安全だからってわけではありません。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/13 15:42

    あぁ、この関数、忘れてましたw
    つい最近、どっかの記事見てこの関数の説明見直したとこなのに。。。
    最近すぐ忘れて困ります^^;

    キャンセル

  • 2018/02/20 08:46

    キャンセル

  • 2018/02/20 09:17

    「最近どっかで見た記事」がまさにこれですね^^;
    ご紹介、ありがとうございます。

    この記事、マニュアルにないことが記述されていて、かなり興味深く読みました。
    今度は忘れないようにしますw

    キャンセル

+1

この辺りの記事がヒントになりそうです。

結局、「これやってれば絶対安全」というのはないので、パスワードそのまま暗号化ではなく何かしら接頭辞つけたり、複数回暗号化を重ねたり、使用する側にも工夫は必要ですね(そういった工夫も外に漏れないように・・・)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.20%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る