- ベストアンサー
ログイン認証機能の選択肢とセキュリティについて
- ログイン認証機能についての選択肢と、その中からの選択基準についての質問です。100文字程度の要約文を3つ作成します。
- ログイン認証機能の選択肢と選択基準についての質問です。要約文をまとめます。
- ログイン認証機能の選択肢と選択基準について質問があります。要約文をまとめると100文字程度になります。
- みんなの回答 (10)
- 専門家の回答
質問者が選んだベストアンサー
PHPでのログイン機能を構築するに当たってのセキュリティの程度とのことですが、 結局はHTMLのフォームタグからHTTPでPOSTを行われた際にPOSTされた処理をするのですから、 それはJavaでもRuby、Perl、Pythonでも一緒です。 XSS対策、SQLインジェクション対策、セッションハイジャック対策など、きちんと行えばよいと思います。 その具体的な実装方法は、 http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_security.html こちらによくまとまってます。 他にも最近(昔からでしょうか)では、パスワードをDBに格納する際にMD5でハッシュ化しておくなどの 対策をしたりするようです。 そのほか、パスワードを忘れた人のためのパスワードリマインダの実装が必要なのかどうなのかとか、 ユーザが設定しようとしているパスワードの暗号強度が良いのか悪いのかのナビゲーションをするのかとか、 ログイン機能以外に気を回す必要のある箇所もたくさんあります。
その他の回答 (9)
- JavaJavax2
- ベストアンサー率22% (68/305)
>この言葉からは、あまり良い印象を受けませんでした。 そりゃそうでしょうね。水差しただけのつもりなので。偏見ととったりはしませんよ。長文の返信どうもありがとうございました。 冷やかすだけじゃあれなんで書きますが、そこらへんについて理解したいならWindowsに付属の文字モード表でもみたらよいでしょうね。 じゃぁね。
お礼
書いて頂いたことに対し、スルーをしてしまうのは申し訳ないので、 簡単にお返事を。 >そりゃそうでしょうね。水差しただけのつもりなので。 そうでしたか。 なぜそのようなことをされるのか、よく分かりませんが、 何かしら気になる要素があったのでしょうね。 と、わけのわからないことを言ってみます。笑 >偏見ととったりはしませんよ。 正直にお答え頂き、ありがとうございます。 真意が伝わり、対応しやすくなりました。 >冷やかすだけじゃあれなんで書きますが お土産をどうもありがとうございます。 参考にさせて頂きます。 最後に、私もマネして、 じゃぁの。
- hogehoge78
- ベストアンサー率80% (433/539)
JavaJavax2さん 文面は長いですが、ここで私が説明している内容は、単純に 「md5+saltで指定してやって、saltにする文字列を辞書にも登録されないような値で記述してやればある程度セキュアです」 というだけなんですけどね・・・・ march4さん とりあえずバイナリエディタでも、用意してみたら、どれが文字として認識されなそうか分かると思いますよ。 http://hp.vector.co.jp/authors/VA028375/thebe/
お礼
>文面は長いですが、ここで私が説明している内容は、単純に そう、実は単純なのですよね…。笑 私も同様の認識でおります。 このような説明をわざわざして頂き、申し訳ありません。 >march4さん とりあえずバイナリエディタでも こんなものがあるのですね。 初めて知りました。 では、こちらでいろいろと試してみようと思います。 長くなりましたが、 最後までお付き合い頂き、ありがとうございます。 いつも大変勉強になっております。 バイナリの件で、さらに分からないことがあれば、 別途、質問をさせて頂こうかと思いますが、 恐らく、大丈夫だろうと思います。^^ 今回も、どうもありがとうございました。
- JavaJavax2
- ベストアンサー率22% (68/305)
辞書を集めてアタックテストなどしている者です。 何をそんなに親切に答えてるのかわかりませんが、phpで実装する場合は正しく設置すればそれなりのセキュリティーになりますね。ちゃんとやるならpppに+でSSL暗号化までする必要がありますね。Basic認証でもユーザがIDパスワードを指定する事は可能です。 そんなにセキュリティーを意識して銀行でも始めるのですか。
お礼
>何をそんなに親切に答えてるのかわかりませんが この言葉からは、あまり良い印象を受けませんでした。 私の偏見でしたら、お許し下さい。 上記の言葉は、私に言われているのか、ホゲホゲさんに言われているのか、 これだけでは判断できかねますが、 私に対して、というのであれば、 ただ単純に「知りたいから」とお答えする以外に、答えはありません。 また、ホゲホゲさんに言われているのであれば、 私のために、私の疑問に真っ直ぐに答えて下さっている、 これに尽きるのではないかと思います。 なので、私からすると、大変ありがたい回答者であるため、 「何をそんなに親切に答えてるのかわかりませんが」 と言われてしまうと、正直、良い気はしません。 見て見ぬふりは出来ませんでしたので、 厳しい言い方になっているかもしれませんが、お伝えしておきます。 >そんなにセキュリティーを意識して銀行でも始めるのですか。 「そんなに」という判断は、私の中でも同じかと言えば、そうではありません。 私がここで、質疑応答(ある意味、議論)している話が、 どれほどセキュアーなものであるかは、それについて知識のある方になら分かるのかもしれませんが、 この私にはそれが分かっていないわけです。 また、セキュリティを可能な限り上げようと努力することは、 むしろ歓迎されるべきことなのではとも思います。 これは、程度の話になりますが、 ここで話されている手法における、 セキュリティを上げるのに要する作業量とその難易度については、 それほど高度なことを議論してはいないと思います。 ホゲホゲさんが仰るように、「文面は長い」ですが。笑 私はセキュリティをある程度(私の基準における、ある程度)、 追及しようとするのは、 私のサイトを利用される方達のためを思ってのことです。 自分が納得のいくレベルの安全性を、自分のサイトに求めたい、 ただそれだけです。 これは、いけないことなのでしょうか。 今、ここで議論されている手法が、 銀行レベルのものであるというのであれば、 これほど嬉しい言葉はありません。 もし、本当にそう思われて言って頂けたのであれば。 でも、そうではなくて、 大げさな表現として使われていたのであれば、 正直、残念に思います。 この場合には、何を言わんとしているのか、私には分かりかねます。
- hogehoge78
- ベストアンサー率80% (433/539)
>↑ここで、「\x84\x98\x94\x11」とタイピングされているのは、「入>力できている」ということにはならないのでしょうか? これは、PHPではこの記述方法でその16進数の値をブラウザに出力できるってだけなんですが、 <?php echo "a"; echo "\x61"; //aと表示される ?> 少なくとも辞書アタックの場合、意味のある文字をまとめたDBに登録された値で検索するわけですので、文字データと認識されない意味のないバイナリ値であれば、辞書登録される可能性が格段に低くなるということが言いたいだけなんです。(単語としての意味を成さない情報というだけではなく、文字のスペルとしても意味を成さないため)
補足
>少なくとも辞書アタックの場合、意味のある文字をまとめたDBに登録された値で検索するわけですので 具体的に、辞書アタックというものがどういうことなのか、 理解しておく必要があると感じ、下記のページを見てきました。 ttp://itpro.nikkeibp.co.jp/article/COLUMN/20061128/255161/?ST=slfsys&P=2 ・パスワード:pass ・salt:example ・ハッシュ値(SMD5による):md5('example'.'pass') →例えば、このハッシュ値が 0aka8afa899ara とすると、 ・パスワードDB(対応表)では、 pass 0aka8afa899ara のように記録されるのだと思います。 で、上記URLのページで言うところの「レインボーテーブル(辞書)」を使って、 悪意あるアタッカーがパスワード検索をしてくるのを想定し、 それに対するセキュリティを高める方法として、 以下のものが考えられる、と。 ・パスワードを複雑(予想されにくいもの)にする ・saltを複雑(予想されにくいもの)にする 結局、したいことは、 'ソルト'.'パスワード' この文字列(結合された文字列)を より複雑(予想されにくいもの)にしたいわけですよね。 で、パスワードの値は、その作成において、ユーザに一任されているものなので、 サイト管理者側では、「6文字以上で、英数字それぞれ1文字以上含むものにして下さい!」 くらいしか指定できませんね。 これだと、 yellow777 のような、比較的、辞書登録されやすそうな値を ユーザから受け取ることになってしまうわけで、 これは、セキュリティが低いことを意味するので、 そこで、こちら側(サイト管理者側)で添加物を加えてあげよう、 ということで登場するのがsaltという考え方なのだと思います。 で、このsaltの設定については、サイト管理者側で任意に決められますから、 ここで最大限、複雑なものにしようと、サイト管理者は色々と工夫を試みるわけですよね。 その工夫の1つとして、 前の回答でホゲホゲさんに教えて頂いた、 「文字コードのバイナリに存在しないバイナリ値をsaltにする」 という方法が考えられるのだと思います。 で、ここからが、このバイナリの話の本題になりますが、 「文字コードのバイナリに『存在する』バイナリ」、も、もちろんあるわけですよね。 それだと、「辞書に登録され易さ」で言えば、 文字コードのバイナリに存在しないバイナリに比べ、 登録され易い、ということなのだろうと思うので、 「文字コードのバイナリに存在しないバイナリ」 をsaltに選択し、より一層、辞書に登録されにくい仕組みに すべきだと。 そういう話なのですよね。 そこで、 「文字コードのバイナリに『存在する』バイナリ」とは、なんぞや。 という疑問に応えて頂いたのが、 >echo "\x61"; //aと表示される という箇所なのだと思います。 「\x61」→このバイナリは、「文字のスペルとしても意味を成す」バイナリ なのですよね。 そういうことを説明して頂いたのだと思います。 (この、「a」が「\x61」であるというのは、aが英字であるため、文字コードには関係なく、こういう1対1対応なのですよね? これが例えば、マルチバイトの「あ」という文字になると、選択する文字コードによって、そのバイナリ値も変わってくるわけですよね?) ということで、 「文字のスペルとしても意味を成さないバイナリ」 というものを、saltに使う意義は分かってきましたが、 次の問題は、 その、 「文字のスペルとしても意味を成さないバイナリ」を どうやって見つけてくるか、にあると思っています。 ネットで検索すると、すぐに出てくる類のものなのでしょうか。 詰まる話、「文字のスペルとしても意味を成さないバイナリ」のうちの1つが分かれば、事足りる話なのですよね、おそらく。 以上、長文となりましたが、 何か、変なことを言っておりましたら、ご指導下さい。^^; よろしくお願い致します。
- hogehoge78
- ベストアンサー率80% (433/539)
>「通常入力されない」とありましたが、 >ハッシュ値自体はログインフォームでは入力されないので、 >これは、どういった意味なのでしょうか。 つまり、現状でMD5の解読を行う方法は提示されたURLのように、辞書アタックで行うわけですから、saltを文字列以外のもので生成すれば、辞書に検索かけても文字データではないので、適合するものが出現しないのではないかという意味です。 文字コードのバイナリに存在しないバイナリ値をsaltにするということですね。 saltの推測を 難しくし、抵抗したいという考えのもと、「\x84\x98\x94\x11」とかそもそも入力を行うことが出来ない(どの文字エンコードでもまともに表示されない)ので、このようなものをsaltで付加すれば、辞書アタックには対応ができるな、と。 タイムスタンプを使う場合は、結局組み合わせるタイムスタンプをDB上においてあるので、実質上、ヒントが取得されると想定したDB上にあるので、あんまり良くないと思います。 例示されたURLに記載のSMD5関数の考え方は、考えてみましたがどうやって照合ルーチン書けばいいのか分かりませんでした。 理解力が無くてスミマセン。 >この場合、【2】、【3】、どちらも安全ということになりますでしょうか? レンタルサーバによっては、【3】を、ドメイン適用前のサブドメインのURL叩けば開けてしまう設定になっていることもあるので、あまりオススメできませんが、設定をきちんとやっているのであれば、良いのではないでしょうか。sakuraインターネットで、マルチドメインを行った場合、素の状態ですと、 http://{userid}.sakura.ne.jp/ でアクセスできます。 なので、明示的に、自分自身で設定したのを確認できたところとか、public_htmlの上のように、apacheの設定でまずwebの公開ディレクトリになっていないであろう箇所に置いたほうが安全です。
補足
今回の回答により、おかげさまでドドッと理解度が深まりました。 私は毎回、補足が長くなるため、 お読み頂くのに苦労されていることと思います。 なるべく、私の頭の中をお見せすることで、 回答者の方々に二度手間をさせることのないようにと思っておりますが、 一方で、私のコメント量が増えてしまうことによるお手数をお掛けしており、 なんとも申し訳なく思っております。 それでは、本題に移らせて頂きます。 >saltを文字列以外のもので生成すれば、辞書に検索かけても文字データではないので、適合するものが出現しないのではないかと まず、この概念、つまり、文字データではない文字列(?)というものがあるということ、 そういった概念で対処する方法があることを、 ここで初めて知りました。 どおりで、前回頂いた回答で理解できなかったわけです。 しかし、今回の回答により、かなり理解が進んだような気がします。 >文字コードのバイナリに存在しないバイナリ値をsaltにするということですね。 「文字コードのバイナリに存在しないバイナリ値」 この点が、ちょっと分かりませんでした。 推測した考えを、ここで披露させて頂こうかとも思いましたが、 逆に面倒な結果となりそうなので、書かずにおきます。笑 文字コードそのものの理解から始まりそうなお話なので、 どうしたものやら…。 でも、結局、書いちゃう。笑 えっと、各種文字コードにおける、各種の文字は、 結局は機械が理解できるデータを機械に渡すカタチで、 処理されるわけですよね。 で、そのデータがバイナリデータなのだと思います。 ある文字コードの、 ある文字のバイナリは、例えば「\x84」といったような。 で、そういったバイナリに該当しないバイナリ値というものが存在し、 その値であれば、「hugamogera」のようなテキストデータよりも…、 えっと、何なんでしょう…。笑 >「\x84\x98\x94\x11」とかそもそも入力を行うことが出来ない ↑ここで、「\x84\x98\x94\x11」とタイピングされているのは、「入力できている」ということにはならないのでしょうか? テキストデータであろうと、バイナリデータであろうと、 結局は、何らかの文字を打ち込むことに変わりはない気がするのですが…。 >(どの文字エンコードでもまともに表示されない) 「\x84\x98\x94\x11」としては表示されてますよね? これを、バイナリではない「人間側のデータ(テキストとか画像とか音楽とか)」に変換しようとしても、 「まともに表示されない」という意味なのでしょうかね。 でも、「まともに表示させる意味」が私には分からずに居ます。 $salt = "\x84\x98\x94\x11"; $salt = "hugamogera"; どちらも、文字列には変わりない気がするのですが、 何かどこか、私の理解が足りないのでしょうね。 それは一体、何なんでしょう。^^; >タイムスタンプを使う場合は、結局組み合わせるタイムスタンプをDB上においてあるので、実質上、ヒントが取得されると想定したDB上にあるので、あんまり良くないと思います。 「文字コードのバイナリに存在しないバイナリ値」 をsaltにしたほうが、安全そうだということは、 なんとなく、こんな私でも分かる気がします。 よって、タイムスタンプ方式は、使用しないことに決めました! >どうやって照合ルーチン書けばいいのか分かりませんでした。 理解力が無くてスミマセン。 私は照合の所まで、頭が進んでいなかったため、 実際のコーディングについては、 まだ目を通してはおりませんでした。 ホゲホゲさんが分からないものは、 言うまでもなく、私にも恐らく分からないでしょう。^^; >レンタルサーバによっては、【3】を、ドメイン適用前のサブドメインのURL叩けば開けてしまう設定になっていることもあるので、あまりオススメできません では、【2】の階層にしておきます。笑
- hogehoge78
- ベストアンサー率80% (433/539)
>×複合→○復号 >です。 >すみません、誤字がありました。 失礼しました。 >それとも、辞書そのものが作成されて、公開されているような感じでしょうか。 >http://www.netaro.info/~zetaka/burogu/archives/000104.html それですね。 >とのことなので、SMD5(saltを使った、結局はMD5ですよね)を使おうかと思います。 パスワードを管理するデータに対して、毎回生成するランダムな値を付加してしまったら、パスワードを照合すること自体が出来なくなってしまいますよ。saltは固定値でなければいけません。 saltを通常じゃ照合できない値にしたいのであれば、絵文字のようなバイナリや、文字以外のバイナリを付加してやればよいと思います。 <?php $salt = "\xF8\x9F"; $encrypted = md5($salt.$pssword); ?> とか。 PHPでは「"(ダブルクオーテーション)」内では、「\xFF」といった値を利用できるので、これを通常入力されないような値にすればよいのではないかなと。 それで、アクセスされたくないファイルの置き場所ですが、 xreaって、ユーザ名の直下にディレクトリやファイル置けませんか? マルチドメインで(というかドメインを付加してない状態)しか、使っていないのであれですが、public_htmlと同列にファイルやディレクトリが置けます。(つまり/hogehoge/user_id/{ここに。})
補足
>毎回生成するランダムな値を付加してしまったら、パスワードを照合すること自体が出来なくなってしまいますよ。saltは固定値でなければいけません。 確かに、そうですよね。 えっとですね、タイムスタンプをsaltに、というお話は、 前記しました下記のサイトから得た情報です。 ◆ttp://www.developlus.jp/topics/password.html <引用> まず、ランダムな文字列Saltを生成します。これは、そのときに時間を種にしてランダム関数等を用いれば、まったくランダムな文字列を手に入れることが可能です。このSaltを元にパスワードのハッシュ値を取ります。生成されたハッシュ値にSaltを付加します。認証を行う際は、保存されているハッシュ値よりSalt部分を抜き出し、送信されてきたパスワードにSaltを付加します。このハッシュ値と保存されているハッシュ値を比較することで、パスワード認証を実施します。 ----- で、タイムスタンプの方法の場合、 ユーザ毎にsaltが変わることになりますが、 これは、パスワード登録時のタイムスタンプを固定値として 使い続けるというものだと思いますので、 この場合には、恐らく問題なくsaltとして機能すると思います。 つまり、DBに登録日時のタイムスタンプも一緒にインサートしておき、 それをsaltとして使うということですね。 こうすることで、ユーザごとにsaltを変えることができるというメリットが恐らくあるのでしょう。 私がただただタイムスタンプとだけ言ったので、 恐らく、ホゲホゲさんは、 ログインの度にsaltが変わるシステムを想像されたのだと思います。 誤解を招くような書き方をしてしまい、申し訳ありません。 >「\xFF」といった値を利用できるので、これを通常入力されないような値にすればよいのでは えっと…。 「通常入力されない」とありましたが、 ハッシュ値自体はログインフォームでは入力されないので、 これは、どういった意味なのでしょうか。 私の、 「saltを見破られにくくした方が良いのでは」、という考えは、 まず、 SMD5ハッシュされたパスワードDBファイルを不正に取得されてしまった、ということを前提としています。 このパスワードDBファイルの解読には、saltが必要ですよね。 で、不正取得した悪意有る人間に対し、出来る限り、そのsaltの推測を 難しくし、抵抗したいという考えのもと、 yellowではなく、hugamogeraの方が良いのでは、と思った次第です。 (何か変なことを言っていたらごめんなさい…。) なので、hugamogeraよりも、「\xFF」の方が、より安全であるという意味が、 正直、よくわかりませんでした。理解力が無く、すみません。 >つまり/hogehoge/user_id/{ここに。} 【2】 /hogehoge/user_id/public_html/ #ここで、ようやく置けるように。 私はこの【2】の階層を、 ホゲホゲさんが仰る{ここに。}の階層とイコール として、書いていました。 えっと、私の書き方が良くなかったですね。 恐らく、ホゲホゲさんはさらに下の階層を想定されたのだと思います。 私の書き方がまずかったですね、すみません。^^; よって、【3】の階層も同様の理解で、 1階層、上にあげて考えて頂けると嬉しいです。 この場合、【2】、【3】、どちらも安全ということになりますでしょうか? というのが、前回の補足における、質問でした。 【2】が安全なんだから、それで充分なのでは? と思われるかもしれませんが、【3】も安全であるか確認しておきたいなと思いまして…。 どうぞよろしくお願い致します。
- hogehoge78
- ベストアンサー率80% (433/539)
>MD5ハッシュの解読ソフトがフリーで公開されているようなので、 >パスワード/IDファイルが不正に取得されてしまったら、 >(不正に取得するだけの力のある人であれば、上記フリーソフトを使う等して、すぐに復号化されてしまいそうなので)、完全にアウト!という気がしてなりません。笑 複合化、では無くて解読、でしょうか。 ネット上でもよく書いてありますが、辞書を用意して、その組み合わせからデータを算出してくればよいわけですよね。 aaa,md5(aaa) bbb,md5(bbb) の組み合わせの辞書DBでも用意すればたまたまパスワードが辞書に引っかかれば解読は出来ます。 この場合の話であれば、 <?php $salt = 'hogemoge'; $encrypted = md5($salt.$password); ?> などと別の値を付加してやれば、ある程度は回避できます。 >やはり、取得されないようにすることが一番大切なのでしょうね。 その通りですね。 >パスワードの管理の仕方などについて、 >サイト上で説明すべきなのでしょうかね。 それは説明しないほうが良いでしょうね。プライバシーポリシーとしての内容以外で これこれこのようにしています、なんて話を書いても、それをハック/クラックのヒントにされるだけですし。 >>単純にそのファイル名がばれてしまえば、URL叩けばダウンロードできてしまいますよね。 >えー。驚 >それは困る。苦笑 zipファイルなど、Webサーバの設定ファイルに送出するheaderや、ファイルタイプが設定されていない場合 全部バイナリデータとしてただダウンロードされますので、当然といえば当然ですね。 PHPスクリプトだって、Webサーバが対応してなければ、ただのファイルとして扱われ、ソースが流出します。 >時々、PHPファイルを不正取得されませんか?とか、 >ファイルの内容を盗み見されませんか?などといった事を >心配されている方がいらっしゃるようなので、 >私もちょっと心配していました。苦笑 Webサーバが正しくファイルタイプを認識していれば正しく表示されますので、 正しく設定しているのにソースが流出するようであればソレはWebサーバのセキュリティホールで 即刻サーバのアップデートを行う必要がありそうですが、どうでしょう。詳しくは分かりません。 >ユーザ以外の「その他」(つまり、Apacheさんを想定)に対しても書き込み権限を与えないと、 >正常にDB処理をしてくれないのかな、なんて思っていますが、どうなんでしょうかね。 >やはり、書き込み権限をユーザ以外に与えるようだと、 >セキュリティは低下しそうでしょうか。 パーミッションとは、Linuxの実行権限のことです。詳しくはパーミッションとかLinuxとかで検索してみてください。 Linuxがどのようにユーザ管理をしていて、各アプリケーション(apacheとかmysqlとかsendmailとかソフトウェア)の 実行権限をどのようにしているかという話が分かると思います。 (雰囲気で何となく分かっている程度なので文章に出来ませんでした。ごめんなさい) >又は、保存用ファイルの置いてあるディレクトリに.htaccessファイルを置いておく。 はい、この方法で、 DBファイルと、インクルードファイル(.inc)など、複数の拡張子に対するアクセス制限を、一括で行うつもりです。 >public_htmlと同階層は安全だけれども、 >example.com(ドメインの階層)は安全ではないことになりますか? >(くどくて、すみません。苦笑) 置いてあるファイル名が分かれば、少なくともブラウザを用いてHTTP経由でアクセス(実行)を試みることが出来るわけですから .htaccessファイルの設定漏れ(又はミス)でファイルをダウンロードされる可能性もありますし、 何らかのセキュリティホールを突かれてファイルを持ってかれる可能性もあります。 MD5やSHA1でハッシュ化するのと同様に、可能性を少しでもつぶす、ということですね。
補足
>複合化、では無くて解読、でしょうか。 ×複合→○復号 です。 すみません、誤字がありました。 >ネット上でもよく書いてありますが、 方法が書かれているということでしょうか? それとも、辞書そのものが作成されて、公開されているような感じでしょうか。 (変なことを言っているかもしれません…。) http://www.netaro.info/~zetaka/burogu/archives/000104.html ↑例えば、このような。 >辞書を用意して、その組み合わせからデータを算出してくればよいわけですよね。 えっと…、 MD5ハッシュ値は、 同じ値から得られるハッシュ値は、常に同じ値(一意に決まる値)となるので、 辞書を作ることができるわけですね? で、その辞書は、当然、誰が作っても同じものになると。 なるほど。 //------------------------------------------------ <?php $salt = 'hogemoge'; $encrypted = md5($salt.$password); ?> などと別の値を付加してやれば、ある程度は回避できます。 //------------------------------------------------ この例の場合、saltとして使う文字列は、 より分かりにくいものの方が良いということですよね? 例えば、 yellowというsaltを設定しておいた場合に、 ユーザがパスワードにmonkeyを登録してきたら、 yellowmonkeyのハッシュ値がDBに保存されることになりますが、 これは、ハッシュ値の辞書に登録されてありがちな文字列になりそうなので、 その意味で、yellowという文字列は、saltとしては適当ではない、 ということになりますでしょうか。 yellowmonkeyが辞書にありがち、と私が言ったのは、 yellowmonkeyという文字列が、意味のある文字列であると 私は思っているからです。 人というものはパスワードに無意味な文字列よりか、 覚えやすく忘れにくい「意味のある文字列」を使うでしょうから、 辞書もそれを考慮し、意味のある文字列を優先的に収録していると私は思っている、ということです。 なので、saltに入れる文字列は、 hugamogeraのような、意味不明な(ランダムな)文字列の方が良い、ということになりますでしょうか? (考え方的に。) また、saltには、タイムスタンプを使うこともできるようですね。 ttp://www.developlus.jp/topics/password.html こちらに、ハッシュについてよくまとめられていました。 このページによると、 昨今、MD5でパスワードを保存することはナンセンスで、一般には用いられません。 とのことなので、SMD5(saltを使った、結局はMD5ですよね)を使おうかと思います。 >(雰囲気で何となく分かっている程度なので文章に出来ませんでした。ごめんなさい) いえいえ、調べる指針やきっかけを与えて下さり、 毎回感謝しております。 /hogehoge/user_id/public_html/example.com/index.php サーバの「絶対パス」がこのようなものになるサーバの、レンタルスペースにおいて(某●REA.com)、 【1】 /hogehoge/ #ここにはファイルを置く権限がない /hogehoge/user_id/ #同上 【2】 /hogehoge/user_id/public_html/ #ここで、ようやく置けるように。 【3】 /hogehoge/user_id/public_html/example.com/ #同様に置けます。 【4】 /hogehoge/user_id/public_html/example.com/index.php #既に置いてます。笑 上の【1】~【4】の各階層において、 パスワードDBファイルを置いておいても安全な(つまり、URLを叩いてアクセスされない)階層というのは、 【2】【3】ということになりますでしょうか?? 【1】は、そもそもサイト管理者すらアクセスできないので論外で、 【4】も言うまでもなく、基本的には誰でもアクセスできてしまう階層なので、これもアウトですね。 で、【2】は安全そうだなと思うのですが、 気になるのが、【3】です。 これも安全と考えられますよね? (ちょっと自信が無かったりする…。) 例えば、【3】の一例として、 /hogehoge/user_id/public_html/passward.sqlite/ という感じで、パスワードDBを上記階層に置いた場合、 そのファイルにURLを叩くことでアクセスするとなると、 http://passward.sqlite ↑これを叩くことになるわけで、 そんなアクセスはできるわけはないと。 よって、【3】も安全であると。 どうでしょう。 どこか、誤解がありましたら、ご指摘下さい。 よろしくお願い致します。
- hogehoge78
- ベストアンサー率80% (433/539)
>(銀行サイトなどのセキュリティは、クッキーやIPアドレス以外の方法で、 この手のアタックを回避していたりするのでしょうかね。余談ですが、気になりました。) どのようにされてるんでしょうね・・・・ アタックをかけられている場合は、サーバ側で記録してサーバサイドでも何らかの処置を施すのかもしれませんが。 どうなんでしょうね。勉強不足ですみません。 >そうですね。 >しないよりかはしたほうが、より安全にはなりそうですよね。 ただ、懸念点としては、特段個人情報を扱わないサイトとかですと、 ユーザもパスワードをすぐ忘れたりして、何度もパスワード入力を試みるというケースもあります。 5回とかだと結構厳しいのかなぁと。 実際この手のロック手法は、色々と参考サイトありそうですね。探してみてはいかがでしょう。 >よって、MD5などを使う場合でも、 >結局は、その暗号化された文字列は見られてはいけないということなのでしょうね。 >したがいまして、 >結論としては、ファイルの置き場選択が1番重要という考えに至りました。 結局はデータベースの内容を何らかの方法でID/パスワード一覧として見られてしまった場合でも すぐにそれらの結びつきが見えなくするって為の方法ということですね。 >あ、ハッシュ化は、管理者自身(つまり、私)に、パスワードを知られないための処置とも言えそうですね。 >それは考え過ぎでしょうか?笑 ソレもあるかもしれませんよ。友達とか知り合いのような人にサイトに登録してもらうに当たって、 出来れば見えないほうが健全と言えるかなと。 >これは、一体、どういう仕組みで、 >不正にファイルを取得されてしまうのでしょうか? 単純にそのファイル名がばれてしまえば、URL叩けばダウンロードできてしまいますよね。 >具体的に、パーミッションの設定をどのようにしておけば、 >仮に、WEBルートより下の階層に置いておいたとしても、 >安全に管理できますでしょうか。 http://mymemonote.blog105.fc2.com/blog-entry-45.html パーミッションは、600ですね オーナーが書き込み及び読み込みが出来て、それ以外のユーザは何も出来ないと。 又は、保存用ファイルの置いてあるディレクトリに.htaccessファイルを置いておく。 --------.htaccess------------------ <Files ~ "\.file$"> deny from all </FIles> ----------------------------------- この例では拡張子が「file」のものをアクセス禁止としています。 適時変えてください。 ただ、最も安全なのは前回伝えたとおりで、Webルートより上の階層に置くことです。 >「WEBルートより上」というのは、 >public_htmlディレクトリと同階層ということになりますでしょうか。 >私が使用している●REA.comのレンタルサーバですと、 >public_htmlディレクトリの直下にドメインディレクトリがありますが、このドメインディレクトリでは、安全ではないのですよね? そういうことですね。 http://example.com/index.html でアクセスされるファイルが、/public_html/index.htmlとなるわけですから、 ソレより上にあれば、WEBからアクセスすることは困難ですね。 >SSLには興味があるので、ちょっと調べてみようかと思います。^^ ちなみにSSLは通信を暗号化しますが、 ID/パスワードをメールで通知するといった場合は、メールは平文なので、ダメです。 パスワードは通知しないようにしたりしないと、SSLの意味がないですね。 FTPも同様に平文で通信してますので、個人情報を取得するアンケート結果のようなものを ローカルに保存しなおす(CSVファイルやSqliteファイル)場合にそのままダウンロードするのも 同様な理由でよくないですね。 とはいえ、SFTP/SCP/FTPSなどがレンタルサーバで対応されていなければ、FTPを使わざるを得ませんが。
お礼
>ID/パスワードをメールで通知するといった場合は、メールは平文なので、ダメです。 パスワードは通知しないようにしたりしないと、SSLの意味がないですね。 なるほど~。 だから、パスワードをメールで通知してこないサイトが多いのですね~。 長年の疑問が解けました。 ただ、時々ですが、パスワードをそのままメールで送ってきてくれる(送ってきてしまっている)サイトもありますよね。 親切なサイトだと思っていましたが、 あれは逆に不親切だったのですね。苦笑 セキュアーなメール送信方式でも採用しているのなら、話は別ですが…。 >FTPも同様に平文で通信 いや~、勉強になります。 FTPについても、覚えておきますね。 >とはいえ、SFTP/SCP/FTPSなどがレンタルサーバで対応されていなければ、FTPを使わざるを得ませんが。 ●REA.comさんではFTPSを利用可能なようですので、 適宜、利用しようかと思います。 ところで、 実際、httpやftp通信の間で、データを不正取得することは、 簡単にできてしまうものなのでしょうか? 私が知らないだけで、 そこらへんのフリーソフトをちょちょっと触るだけで、 不正取得できてしまうくらい、たやすいことなのだとしたら、 正直、かなり困ります。苦笑
補足
>5回とかだと結構厳しいのかなぁと。 ちょっとサディスティックでしたかね。 では、10回まで見逃してあげることに致します。笑 MD5ハッシュの解読ソフトがフリーで公開されているようなので、 パスワード/IDファイルが不正に取得されてしまったら、 (不正に取得するだけの力のある人であれば、上記フリーソフトを使う等して、すぐに復号化されてしまいそうなので)、完全にアウト!という気がしてなりません。笑 もちろん、ハッシュしないよりかはしたほうが良さそうなのは言うまでもないので、 念のため、ハッシュしておきますが、 やはり、取得されないようにすることが一番大切なのでしょうね。 >ソレもあるかもしれませんよ。友達とか知り合いのような人にサイトに登録してもらうに当たって、 出来れば見えないほうが健全と言えるかなと。 なるほど。ソレもアリでしたか。 ただ、登録してもらう相手に、 「ちゃんとMD5でハッシュしてるから、安心しなさい。」 と伝えるようなものでもないですよね?笑 今まで考えたことはありませんでしたが、 パスワードの管理の仕方などについて、 サイト上で説明すべきなのでしょうかね。 「当サイトでは、通信時にはパスワードを暗号化しております。」 といったような。 >単純にそのファイル名がばれてしまえば、URL叩けばダウンロードできてしまいますよね。 えー。驚 それは困る。苦笑 えっと、 PHPスクリプトファイルについては、 URLを叩いても、HTMLとして出力されるだけですから、 こちらに関しては、DLされてしまうことはなさそうですよね? そんなことはない?! 時々、PHPファイルを不正取得されませんか?とか、 ファイルの内容を盗み見されませんか?などといった事を 心配されている方がいらっしゃるようなので、 私もちょっと心配していました。苦笑 テキストファイルや、DBファイルは、URLを叩いたら、 すぐにDLできてしまいそうなのは、なんとなく想像できます。 >パーミッションは、600ですね オーナーが書き込み及び読み込みが出来て、それ以外のユーザは何も出来ないと。 なるほど。 ただ、DB処理関連のファイル(DBファイルとか)には、 ユーザ以外の「その他」(つまり、Apacheさんを想定)に対しても書き込み権限を与えないと、 正常にDB処理をしてくれないのかな、なんて思っていますが、どうなんでしょうかね。 やはり、書き込み権限をユーザ以外に与えるようだと、 セキュリティは低下しそうでしょうか。 >又は、保存用ファイルの置いてあるディレクトリに.htaccessファイルを置いておく。 はい、この方法で、 DBファイルと、インクルードファイル(.inc)など、複数の拡張子に対するアクセス制限を、一括で行うつもりです。 >http://example.com/index.html でアクセスされるファイルが、/public_html/index.htmlとなるわけですから、 /hogehoge/user_id/public_html/example.com/index.php 私のサイトの相対URIは上記のような形式となります。 (●REA.comでの話です。) で、この場合、 public_htmlと同階層は安全だけれども、 example.com(ドメインの階層)は安全ではないことになりますか? (くどくて、すみません。苦笑)
- hogehoge78
- ベストアンサー率80% (433/539)
>お久しぶりです、hogehoge78さん。 お久しぶりです。 >多くの場合、formから受け取る値を適切にサニタイズできれば、 >問題は回避できそうですね。 そうですね。基本的に外部から来た値は信用しない、という方向で。 自分で付加したページIDのようなGETパラメータなんかは特に気をつけたほうが良いですね。 >まず、IDとPASSWARDを入力→登録するformを作り、 >受け取った値はそれぞれmd5ハッシュしてDBへインサートして登録します。 >そして、ログイン時には、ログイン画面のformにデータを入力させてPOSTで受け取り、その値をmd5ハッシュしたものと、DBに登録されている値とを比較し、 >等しければログインさせる、というような方向で考えています。 IDをMD5で不可逆な暗号化(ハッシュ化)を行ってしまうと、 会員IDに紐付けた別のデータを参照するとき困ってしまいますよ。 管理画面上で、どの会員が何をしている、とかアクセスランキングをつけるとかいった場合にも、 会員のIDがハッシュ化してしまうと読めないとおもいますので、IDはそのままでもいいんじゃないでしょうか。 >不特定多数の人間や悪意あるプログラムによる、 >ランダムにログインを試みる行為を抑止する機能を付加したいと考えています。 >具体的には、5回ログイン作業に失敗したら、その後30分間は、 >ログイン作業ができない、といったような機能です。 行うとしたらIPアドレスぐらいしかないかなと思います。 仰るとおりクッキーは改変可能ですし、削除してしまえばいいと。 適当なテーブルを用意して、ID/PASSの認証に失敗したら記録する感じで、 ●フィールド ipaddr,accesscount,modified ・フォームに値が入力されPOSTされたらIPアドレスのチェック ・既にaccesscountの値が「5」であったら、modifiedに記録したタイムスタンプをチェック。30分以内だったらエラーを吐いてやる ・30分経過をしていたらIPアドレスが含まれるレコードをDELETE ・テーブルにIPアドレスが存在しなかったらINSERT(modifiedは生成/更新日時のタイムスタンプ) ・存在していたら、accesscountを加算、modifiedを現在時刻のタイムスタンプにUPDATE こんな感じでしょうか。 >この手のセキュリティ強化策の実装は、実は難しかったりするのでしょうか? 私自身、ブルートフォースアタックのようなものに関してはあまり対策したことが無いのですが、 上のような方法で制御は出来ます。IPアドレスが変更された、とか、携帯電話のようにアクセスするたびにIPアドレスが変動すると 対処できないですが、実際何度もID/PASSを入れなおす作業はコンピュータが自動的にアタックかけるような仕組みと思いますので 上記の方法でもある程度は防げるのではないでしょうか。 >あとですね、ハッシュの選択肢も色々ありそうなのですが、 >md5ハッシュがやはり一般的なのでしょうか。 >sha1とか、よくわかりませんけど、色々ありますよね。笑 http://ja.wikipedia.org/wiki/MD5#.E3.83.8F.E3.83.83.E3.82.B7.E3.83.A5.E3.81.AE.E8.A1.9D.E7.AA.81.E8.80.90.E6.80.A7.E3.81.AB.E3.81.A4.E3.81.84.E3.81.A6 こんな内容とか、 後はどっちの関数を使ったほうが早いかとか。 結局はDBが不正に取得されてもすぐにパスワード認証が行えないのが目的なので、どちらでもかまわないと思います。 >それと、パスワード等のデータを記録しておくDBファイルの置き場(ディレクトリ)についても、アドバイスを頂けると嬉しいです。 >SQLiteはDBと言っても、所詮、「ファイル」であるため、SQLiteはMySQL等に比べてセキュリティ的に多少弱いというような話を小耳に挟みまして…。 >(真偽の程は謎です。) >ファイルだと、適切に管理しないとダウンロードされてしまうことも起こりうるのでしょうかね? はい、単純にテキストデータをファイルに記録しているだけなので、WEBルート以下においてあって適切なパーミッションを切らなければ、取得されてしまう可能性は十分にありますね。 なのでWEBルートより上の階層においてください。 >あとは、HTTP通信時にハッシュ化される前の生データ(POSTされたデータ)が見られてしまうとか、、、そういうことも気になっていたりします。 これはログインフォームにSSLをかけることで通信を暗号化すれば問題ないです。 基本、個人情報を取り扱うようなサイトでないのであればここまでしなくても良い機はしますけど・・・ レンタルサーバだと、共有SSLというものもありますので適用してみてもいいかもしれないですね。
お礼
早速の回答、どうもありがとうございました。 補足の中で、またしても様々な質問を展開してしまい、申し訳ありません。 もし何かご存知でしたら、教えて下さい。 よろしくお願い致します。
補足
>会員IDに紐付けた別のデータを参照するとき困ってしまいますよ。 確かに! >仰るとおりクッキーは改変可能ですし、削除してしまえばいいと。 大手サイトのログインで採用されている方式も、 結局はIPアドレスチェックによるものなのでしょうかね。 でも、毎回IPが変わるクライアントもありますしね…。 クッキーと両面で、ということも考えられますが、 IPが毎回変わる、かつクッキー操作をしたりするユーザだと、 このセキュリティ対策をかいくぐることができそうですよね。 もっとも、クッキー削除をコツコツと繰り返しながら地道にローテクにアタックするようなレベルの人には、突破されない気もしますが。笑 (銀行サイトなどのセキュリティは、クッキーやIPアドレス以外の方法で、 この手のアタックを回避していたりするのでしょうかね。余談ですが、気になりました。) >適当なテーブルを用意して、ID/PASSの認証に失敗したら記録する感じで なるほど。 IPアドレスとレコードは「1対1対応」、にするわけですね。 で、アクセスの度にUPDATEしながら、その都度、判定をすると。 この方法を使わせて頂きます! >上記の方法でもある程度は防げるのではないでしょうか。 そうですね。 しないよりかはしたほうが、より安全にはなりそうですよね。 >後はどっちの関数を使ったほうが早いかとか。 速さについてはかなり気になります。笑 ttp://www.geocities.co.jp/HeartLand-Gaien/4949/md_hash.html こんな記事を見つけました。 これを信じるのであれば、sha1を選択したい所ですが、 ttp://blog.ohgaki.net/sha1a_sa_a_a_ma_ya_a_a_a_a_sa_ma_fa_a_ma こんな記事もあり、 既存の暗号化方式に対し、やや信用できない気もします。 MD5に関しては、実際にクラックできるフリーソフトなんてのもあるみたいですね。 (wikiのページにリンクがありました。) 余計なものを作りおって…という感じですが。笑 よって、MD5などを使う場合でも、 結局は、その暗号化された文字列は見られてはいけないということなのでしょうね。 したがいまして、 結論としては、ファイルの置き場選択が1番重要という考えに至りました。 (ハッシュ、意味なし?!爆) あ、ハッシュ化は、管理者自身(つまり、私)に、パスワードを知られないための処置とも言えそうですね。 それは考え過ぎでしょうか?笑 >はい、単純にテキストデータをファイルに記録しているだけなので、WEBルート以下においてあって適切なパーミッションを切らなければ、取得されてしまう可能性は十分にありますね。 これは、一体、どういう仕組みで、 不正にファイルを取得されてしまうのでしょうか? また、対策としては、 具体的に、パーミッションの設定をどのようにしておけば、 仮に、WEBルートより下の階層に置いておいたとしても、 安全に管理できますでしょうか。 (私はFFFTPを使わせて頂いております。) 「WEBルートより上」というのは、 public_htmlディレクトリと同階層ということになりますでしょうか。 私が使用している●REA.comのレンタルサーバですと、 public_htmlディレクトリの直下にドメインディレクトリがありますが、このドメインディレクトリでは、安全ではないのですよね? 質問ばかりで、すみません…。^^; >基本、個人情報を取り扱うようなサイトでないのであればここまでしなくても良い機はしますけど・・・ ですよね~。 そこまでして、私のサイトに熱くアタックしてくれる方がいらっしゃったら、ある意味嬉しいくらいです。笑 >レンタルサーバだと、共有SSLというものもありますので適用してみてもいいかもしれないですね。 そうですね。 SSLには興味があるので、ちょっと調べてみようかと思います。^^
お礼
hogehoge78さん、こんばんは。 誰もレスの付かない質問に、またしてもありがとうございます。 毎回、非常に助けられております。 今回もまたザックリな質問でしたが、 とても良さそうなURLをご紹介頂きまして、ありがとうございます。 じっくり読ませて頂きます! (ちょっと時間がかかりそうですが。笑) >パスワードをDBに格納する際にMD5でハッシュ化 「えむでぃー ふぁいぶ(私はそう読んでいる。笑)」によるハッシュ という言葉は、いかにも業界用語っぽいので、気になってました。笑 (マヂで恋する5秒前(MK5)に響きが似ているような。) MD5については全く分かっていないので、教えて頂いたURLにて勉強してきます。 >パスワードを忘れた人のためのパスワードリマインダの実装 実装の手間暇の度合いによります。笑 私にとって敷居が高いということであれば、諦めます。 まずは、パスワードリマインダの内容について勉強してきますね。 >ユーザが設定しようとしているパスワードの暗号強度が良いのか悪いのか JavaScriptが活躍しそうな仕組みですね…(、と勝手な想像です)。 暗号強度に関しては、私には「やり過ぎ」の感がありますので、 ひとまず横に置いておきます。 >ログイン機能以外に気を回す必要のある箇所もたくさんあります。 ほんとですね~。 普段、ログインする側なので、何も考えずに利用していましたが、 設計側では、色々と苦労されているんでしょうね。 ちなみに、まだ「PHPでメールを扱う処理」について習得していないため、 早くもこの点が足を引っ張りそうな予感がしています。 ログイン周りでは、何かとメール機能が登場しそうなので…。苦笑
補足
お久しぶりです、hogehoge78さん。 復活しましたので、引き続き、補足をさせて頂きます。 どうぞ、よろしくお願い致します。 >こちらによくまとまってます。 はい、ザーッとですが、読んできました。 内容が多く、また濃くもあったので、半分も理解できていないかもしれませんが、 漠然とですが、セキュリティに関する考え方の土台が身についたように思います。 多くの場合、formから受け取る値を適切にサニタイズできれば、 問題は回避できそうですね。 さて、ログインの話に戻りますが、 私が考えているユーザ認証は、 まず、IDとPASSWARDを入力→登録するformを作り、 受け取った値はそれぞれmd5ハッシュしてDBへインサートして登録します。 そして、ログイン時には、ログイン画面のformにデータを入力させてPOSTで受け取り、その値をmd5ハッシュしたものと、DBに登録されている値とを比較し、 等しければログインさせる、というような方向で考えています。 ここまでで、何か問題がありそうでしたら、アドバイスして下さい。 次に、 セキュリティの強化として、 不特定多数の人間や悪意あるプログラムによる、 ランダムにログインを試みる行為を抑止する機能を付加したいと考えています。 具体的には、5回ログイン作業に失敗したら、その後30分間は、 ログイン作業ができない、といったような機能です。 なんとなく、セッションを使って実現できそうな機能だなと思っていますが、 セッションを使う場合だと、 もし、それに関するクッキーファイルの削除や改変をされたら、とか、 そもそも、クッキーが有効じゃない場合にはどうなるのか、とか ブラウザを変えられてしまったら、等と考えると、 セッションによる方法で良いのか自信が持てません。 この手のセキュリティ強化策の実装は、実は難しかったりするのでしょうか? また、他に簡単な方法で同様の効果が得られる仕組みがありましたら、 そちらでも構わないとも思っています。 方法より、結果を重視していますので! (ただ、PEARなどは使わずに実装できたらと考えています。) あとですね、ハッシュの選択肢も色々ありそうなのですが、 md5ハッシュがやはり一般的なのでしょうか。 sha1とか、よくわかりませんけど、色々ありますよね。笑 それと、パスワード等のデータを記録しておくDBファイルの置き場(ディレクトリ)についても、アドバイスを頂けると嬉しいです。 SQLiteはDBと言っても、所詮、「ファイル」であるため、SQLiteはMySQL等に比べてセキュリティ的に多少弱いというような話を小耳に挟みまして…。 (真偽の程は謎です。) ファイルだと、適切に管理しないとダウンロードされてしまうことも起こりうるのでしょうかね? phpのスクリプトファイル等は、なんらかの方法で、ダウンロードできてしまったりするものなのでしょうか? あとは、HTTP通信時にハッシュ化される前の生データ(POSTされたデータ)が見られてしまうとか、、、そういうことも気になっていたりします。 (そう、やすやすとは見られないでしょうけれども。笑) もし何かご存知でしたら、分かる範囲で結構ですので、教えて頂けると嬉しいです。