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

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

新規登録して質問してみよう
ただいま回答率
85.49%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

4回答

1726閲覧

password_hash()の安全性について

gammaaex

総合スコア8

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

1グッド

20クリップ

投稿2018/02/13 03:49

質問

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

umyu👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

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

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

投稿2018/02/13 12:58

ockeghem

総合スコア11701

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

投稿2018/02/13 04:00

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

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

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

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

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

投稿2018/02/13 04:59

編集2018/02/13 05:00
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2018/02/13 05:58

1つ「password_hash() のほうが安全」になりうるパターンとして、password_hashのアルゴリズムをデフォルトで選んでいると、PHPのバージョンアップでデフォルト設定が強化されていって、それ以降に登録したユーザーについては強化されたアルゴリズムが自動的に反映される、ということがありえます。 ハッシュとともにアルゴリズムなどのデータも持たせているおかげで、password_verifyはアルゴリズム変更後も古いものは古いまま比較可能となります。
退会済みユーザー

退会済みユーザー

2018/02/13 06:12

私はまだ経験したことがないですけど、アルゴリズムを変える場合は、旧ハッシュの置き換え処理を入れる気がします。 (古いアルゴリズムを使用したものは上書きしていくイメージ) その場合はむしろ、password_verify を置き換えなければならないので、やっかいじゃないですかね?(まぁ、大した手間じゃない気もしますが)
maisumakun

2018/02/13 06:19

いえ、password_verifyは「アルゴリズムやコスト、ソルトといった情報」をハッシュ値から取り出すので、password_hashの生成した値なら、パラメータにかかわらず処理可能です。
退会済みユーザー

退会済みユーザー

2018/02/13 06:32

ちょっと説明が下手でしたかね。 password_verify の代わりに、「新アルゴリズムで比較に失敗したら旧アルゴリズムで比較して、合致したら新アルゴリズムでハッシュ化したもので置き換える」って処理を入れる気がします。 デフォルトが切り替わるってことは、多分何らかの脆弱性によるものか、強度不足が心配されたときだと思うので、旧アルゴリズムでハッシュ化したものを残して置けないかなぁと。 って、色々想像を前提に書きましたが、結局想像なんで、あんまりコメント重ねても意味ないですね^^;失礼しました。
退会済みユーザー

退会済みユーザー

2018/02/13 06:34

事実としては、maisumakun さんの言うように、何もしなくても、新パスワードが勝手に新しいアルゴリズムが適用され、かつ、旧アルゴリズムでハッシュ化されたパスワードも問題を発生させない仕組みになっている。ってだけですね。
退会済みユーザー

退会済みユーザー

2018/02/13 06:42

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

退会済みユーザー

2018/02/20 00:17

「最近どっかで見た記事」がまさにこれですね^^; ご紹介、ありがとうございます。 この記事、マニュアルにないことが記述されていて、かなり興味深く読みました。 今度は忘れないようにしますw
guest

0

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

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

投稿2018/02/13 04:06

m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問