2009-09-01 17 views
5

PHPで安全なログインを作成/ website developer guideは自分自身をロールしてはいけないと言いました。だから、Google経由で入手できるサンプルを参照するのは無駄です。PHPでの適切な認証による安全なログイン

あなたはどのようにそれを行うのですか?あなたはレールで世界クラスのアプリを構築していると言いますが、ここで同じライブラリ/テクニックを使えるのでしょうか?

おかげ

+0

フレームワークにとらわれずデータベースに依存しないhttps://github.com/delight-im/PHP-Authをご覧ください。 – caw

答えて

20

Railsでは、一般に既存のライブラリを使用します。認証は間違って行うのは簡単ですし、問題は何度も解決されているため、再度解決する価値はほとんどありません。独自の実装を書くことに興味がある場合は、最新の認証の仕組みを説明します。

ユーザーを認証する単純な方法は、パスワードをデータベースに保存し、ユーザーが送信するパスワードと比較することです。これは簡単ですが、信じられないほど安全です。あなたのデータベースを読むことができる誰でも、誰のパスワードも見ることができます。データベースアクセスコントロールを配置しても、あなた(およびあなたのユーザー)はハックする人に脆弱です。

正しい形式では、パスワードを選択してからサブミットするたびに暗号ハッシュ関数を使用して処理します。良いハッシュ関数は事実上不可逆的です。ハッシュを取ってそれをパスワードに戻すことはできません。ユーザーがログインすると、送信されたパスワードを取得し、ハッシュしてデータベースのハッシュと比較します。この方法では、パスワード自体を保存することはありません。欠点として、ユーザーがパスワードを忘れた場合、パスワードを送信するのではなく、パスワードをリセットする必要があります。

しかし、これでも、特定の攻撃に対して脆弱です。攻撃者がパスワードハッシュを取得し、パスワードをハッシュする方法を知っている場合、辞書攻撃を行うことができます。辞書にあるすべての単語をハッシュして元のものに保ちます。このデータ構造はレインボーテーブルと呼ばれます。次に、辞書ワードハッシュのいずれかがパスワードハッシュと一致する場合、攻撃者はそのパスワードがそのパスワードをハッシュする辞書ワードであると結論づけることができる。要するに、あなたのデータベースを読むことができる攻撃者は、弱いパスワードを使ってアカウントにログインすることができます。

解決策は、パスワードがハッシュされる前に、各ユーザーに固有のsaltと呼ばれる値(通常は連結またはxor'd)と結合されます。ランダムに生成されてもよく、アカウント作成タイムスタンプなどであってもよい。その場合、攻撃者はすべてのパスワードが基本的にわずかに異なるため、虹の表を使用することはできません。彼は(実際には各口座のための)単一の別個の塩ごとに別々の虹のテーブルを作成しなければならないだろう。

私は他の回答者の助言をエコーし​​ます:これは簡単なものではなく、これまでに行われているために行う必要はありません。あなたが自分で行うのであれば、誤ってシステムのセキュリティを損なうことがあります。しかし、何らかの理由で本当に本当に本当にあなた自身で書くことを望むなら、私はそれがどのように行われたかについての(不完全な!)概要を提供してくれることを願っています。

+2

+1 - 非常にいい答えです。 –

+1

+1 - いいですが、長いと散歩。 :震え:私はオーク材のパネル講義会場にいますか? –

+1

ハッシュ化されたパスワードは実際には難しいことではありません。 – Herbert

-2

私の答えは「しないでくださいそれは」

これは、潜在的なセキュリティの落とし穴年代の完全な非常に複雑な領域です。あなたがこの分野の専門家でなければ、あなたは本当にトラブルや問題を求めています。

私は既存の解決方法を検討することをお勧めします。悲しいことに、私はopenid以外の、私がお勧めしたいと思うことは分かりません。私はあなたがここに良い提案を得るだろうと確信しています...

4

Zend Frameworkは、開始するのに適した'Auth' moduleを持っています。また、サイトでWordPressまたはPHPBBのインストールをホストする場合は、これらのテクノロジの認証モジュールを利用してサイトの他のページにサインインする方法もあります。

+0

Zend AuthモジュールはOPの質問を解決しません。さらに、これらの例では複数の安全でない方法を使用しています。結論として、Zend Authはセキュリティ上賢明です。 – Jacco

+0

安全でない?それはあなたの使い方に依存するツールです。それがどのように安全でないかの例/議論を与えるために気をつけますか? Zend_Authは履歴を持つ既存の認証モジュールで、元の質問と同じ "ローリング独自のもの"とは逆です。どのようにそれを満足していないのですか? – MidnightLightning

+0

[例による高度な使用法](http://zendframework.com/manual/en/zend.auth.adapter.dbtable.html)はMD5を使用し、PHP側のチェックではなくパスワードをデータベースに送信します。パスワードをクエリログに表示させるなど)。Zend Guysとの関係は、自分自身の専門家であり、コメントを無視するということです。 – Jacco

2

あなたが認証しようとしているときに見なければならないことは、本当の目標です。

たとえば、私はGoogleログインを使用しています。これは、自分が誰であるかを知る必要があるため、Googleが考えていると信じることができます。だから、そのモデルがあなたのために働くならば、それのための様々なツールがあるので、OpenIDを使って見てください。

あなた自身で行う必要がある場合は、それが安全であることを確認するためのさまざまなテストがあります。

  • 厳密な検証をしていない限り、ユーザーから何も信頼しないでください。
  • httpsを使用すると、ユーザーのパスワードを保護するのに役立ちます。

私はトムが幻想的な反応をしたのでここで私の返答を終わらせます。 Soulmergeによって

0

私はaccepted answer in your other questionはかなりよく、それを述べたと思います。パスワードを塩でハッシュします。それ以外に、トランスポート層にはいくつかのセキュリティーアイデアがあります。

  • パスワードを送信する際にhttpsを使用します。これにより、誰もワイヤでそれらを捕まえることができなくなります(man-in-the-middle attackまたはクライアントは悪質なプロキシを使用します)
  • 代わりに、ログインフォームが送信されるときにjavascriptを使用してパスワードをハッシュすることができます。これにより、パスワードが決して平文で転送されないことが保証されます。ハッシュされた値をサーバー上のsaltで再度ハッシュしてください。 (md5($_POST['postedPwHash'] . $salt)
-1

(何のSSLが利用できない場合)、ややクライアントサーバトランザクションを確保するための良い方法は、それだけでユニークを送って、資格情報から一意のハッシュを作成するための1回限りのランダムなキーを使用することですハッシュをサーバーに送信します。サーバーはこのハッシュを実際の信任状と比較するのではなく、それ自身の生成されたハッシュと比較します。これは中間者の攻撃に対する良い防御を提供するでしょう。欠点は、これを行うには、ユーザーがJSを有効にする必要があります(少なくとも私はそれを使わないでクライアント側のデータを暗号化するための良い方法を知らない)。これは、オンでないときに十分なフォールバックが必要であることを意味します。 JSでフォームを作成して有効にすることもできます。

this libraryは、私が説明した手順を1回書いた簡単なライブラリですが、おそらく改善が必要です。

「ソルト」メソッドやその他のサーバー側のセキュリティ対策の使用に加えて、全体的なハッシングプロセスは、(JSが常にそうであるように)ユーザーには手続き的で、予測可能で、可視であるため、辞書攻撃に対しても非常に脆弱です。

関連する問題