私はすでにStackOverflowでこれを尋ねましたが、これはより適切な場所であると提案され、質問を「移動」する方法が見つからなかったため、コピーする必要があります。
信じて、私は知っている、この問題についての何百もの質問がある。私はパスワードを保存するSAFESTの方法を見つけるためにそれらの略奪品を読みましたが、与えられたすべての答えは私たちがまだはるかによくできるというかゆみを感じることを私に与えます。そして、これをPHPで使用する予定ですが、すべてのコーディング言語に適用できると思います。
私はセキュリティの専門家ではありませんが、1つの方法だけでは十分に安全ではありませんか?
暗号化
使用した文字列がわかっていれば、暗号化されたパスワード(PHPを使用)を復号化してプレーンテキストに戻すことができます。ハッキングされた私が見たほとんどのホスティングアカウントは、最初にファイルにアクセスし、次にconfig.phpなどに保存されているDBパスワードを探します。
大きくて複雑な文字列を使用してパスワードを暗号化した場合でも、侵入者がcreate_account.php(またはユーザーが作成された場所)にアクセスすると、そこで文字列が見つかり、パスワード列全体を復号化することができます。数分(右?)
ハッシング
ハッシュの良いところは、パスワードをプレーンテキストに戻せないことです。これは素晴らしいことですが...多くのハッシュ手法にはエクスプロイトがあり、ハッシュの可能な値(ハッシュ文字列は複数のプレーンテキスト文字列を意味します)。一部の人々は、Amazon EC2を使用してハッシュ化されたパスワードを、弱いパスワードの場合は数秒で、強力なパスワードの場合は数時間で回復できたという記事を読みました。
ハッカーとランダムなj * rksが大量のハッシュ>文字列値を格納するハッシュインデックスディレクトリを見たので、取得したハッシュを入力すると、1秒でパスワードを取得できます。これはまだ辞書攻撃の一種ですが、かなり効果的な攻撃です。
MD5のような一般的なハッシュについては、ハッカーがMD5ハッシュを使用しているため(ファイル名、gravatar.comなどのAPIのように)、MD5ハッシュに何らかの方法でインデックスを付けることを簡単に見つけたため、インデックス付きのHUUUGE辞書がありました値に関連付けるのに1秒しかかからないハッシュの.
MD5とSHA1はかつて安全であると考えられていましたが、その後エクスプロイトが出現しました。現在使用されている信頼できる方法(私はふぐが最高の方法を読んでいますが、それは正しいですか?)が将来的に悪用される場合はどうなりますか?
そして最後に、私はこれがばかげていることを知っていますが、2つのパスワードが同じハッシュ結果を持つ可能性があるので不快です。私が知っている、同じハッシュを持つ他の値を誰かが推測する可能性は非常に低いですが、HEY、私たちは2012年に来ています!飛行機やアバター映画を1時間でレンダリングできるコンピュータがすでにあるはずではなかったのです。 ? :Pもう少し良いものがあるはずです...
塩
Saltを使用してパスワードの取得を難しくした場合でも、ハッカーが固定されたsalt文字列(またはランダムなsaltが格納されている場所)を見つけた場合、クラウドの計算攻撃でブルートフォースを実行することはそれほど難しくありません。 ?
何か良いことはありませんか?
先ほど言ったように、私はセキュリティの専門家にはほど遠いですが、そこに選択肢はないのですか私はこれについてスタックオーバーフローとGoogleの結果(ほとんどがスタックオーバーフローの回答:Dです)でこれに関する多くの質問を読みましたが、彼らはほとんど同じことを言っています.
ハッシュと暗号化が唯一のオプションである場合、それをより良くする方法はありますか?ユーザーを作成するファイルにアクセスした場合に、暗号化パスワードを非表示にする方法はありますか?
これらのすべての答えで、私は誰かが次のような方法を組み合わせるよう提案するのを見たことはありません。
sha1(crypt [blowfish.salt]、salt)これは何らかの理由で悪い考えですか? (私は、何千ものユーザーが登録してログインしているサイトでは、プロセッサの消費が多すぎると考えることができますが、それを使用する予定のサイトで処理できます)
私は「これをコード化してください」と尋ねているのではありません。DBとソースコードが悪用された場合に、パスワードを取得することを「できるだけ不可能」にする(最も難しい:P)方法を知りたいです。
多分私はこれらの方法が機能する方法を誤解し、多分PHP関数がパスワードでも文字列を解読できないようにする関数があるか、多分私は何かを逃しました。それでも誰かが提案したのは奇妙だと思いますメソッドの組み合わせ。
よろしくお願いします。まだ心配している心の考えを読んでいるなら、もう一度感謝します。
認証をネットワーク内の別のサーバーに委任することもできます。プライマリサーバーは、ウェブサービスまたは必要なプロトコルを介して通信します。このようにして、ハッカーはプライマリサーバーとファイルに必要なすべてにアクセスできますが、何も取得できません。
認証サーバーをより厳しくロックダウンして、攻撃の影響を最小限に抑えることができます。攻撃が発生する必要があることは言うまでもありませんviaプライマリサーバー。
パスワードを暗号化しない 一方向)ハッシュします。
パスワードを解読する必要はありません。そうすれば、セキュリティについてそれほど心配する必要はありません。
セキュリティは常にパフォーマンスとのトレードオフです。
標準のハッシュアルゴリズム(md5、sha1)は、ソルトが攻撃者に知られない限り安全です。
低速のハッシュアルゴリズムを使用すると、攻撃者がコードと保存されているハッシュにアクセスできる場合でも、パスワードが安全になります。
---(crypt関数 は、おそらくphpで必要なものです。多数の暗号化ラウンドを使用すると、特定の入力のハッシュの計算が遅くなります。これにより、ブルートフォースを実行できなくなりますが、ユーザー/アプリケーションがユーザーが入力したパスワードが保存したハッシュと同じであることを確認するのが遅くなります。これはトレードオフです。
テクニックを2倍にすることは、セキュリティを高めるために何もしません。saltの暗号化ラウンドパラメータは、入力文字列のハッシュの出力をハッシュアルゴリズムに何度もフィードバックすることを意味します-オーダーメイドの+1を提案しているだけです実行するラウンドの数に1を加えます。さらに、与えられたsha1(crypt[blowfish.salt],salt)
の例では、ハッシュをユーザー入力と正しく比較することができません- 最初の例 から:
パスワードを比較するためのソルトとしてcrypt()の結果全体を渡す必要があります
Cryptの出力がないと、ユーザー入力を既に生成されたハッシュと比較できません。
最も安全なパスワードの保存方法は?レインボーテーブルと並行してパスワードを攻撃しないようにする、数バイトのランダムソルトを備えた強力な低速ハッシュ(bcryptなど)。パスワードの暗号化は、絶対に必要な場合にのみ使用する必要があります。例: パスワードを外部システムに記録する 制御できないことで、サードパーティのアクセスを許可する適切なプロトコルを使用することはできません(など) openauth)、そのため、そのシステムでユーザーのパスワードを記録する必要があります。
そして最後に、私はこれがばかげていることを知っていますが、2つのパスワードが同じハッシュ結果を持つ可能性があるので不快です。私が知っている、同じハッシュを持つ他の値を誰かが推測する可能性は非常に低いですが、HEY、私たちは2012年に来ています!飛行機やアバター映画を1時間でレンダリングできるコンピュータがすでにあるはずではなかったのです。 ? :Pもう少し良いものがあるはずです...
はい、あなたの不快感はばかげています。たとえば、SHA256(256ビット)またはbcrypt(184ビット)を使用すると、2つのランダムなパスワードが同じハッシュに到達する可能性は非常に低くなります(約1066 パワーボールのジャックポットを獲得するよりも確率が低い)。 SHA256の場合、約2になるまで、すべてのパスワードは一意である必要があります256/2 〜1038 パスワードはテーブルに保存され、その後半分の時間で1セットの重複したパスワードになります。これを取得するには、特定のパスワードに同じハッシュにマップされる2番目の文字列が含まれている可能性が高いため、おおよそ2が必要です。256 〜1077。 (これらはすべて、ハッシュ関数が優れた均一性を持っているという前提の下にあります)。
これらの大きな数値を考えてみましょう。地球の質量は約6x10 ^ 24 kgです。したがって、各パスワードをRainbowテーブルに格納するために平均50バイトを使用する場合、SHA256で1つの重複が存在する可能性が高い前に、約10 ^ 30ギガバイトのデータが必要になります。これを3つすべての観点から言えば、TBハードドライブの重量はそれぞれ約0.5 kgです)、ハードドライブの重量は地球の約1000倍になります。または、ほとんどのハッシュには複数の文字列があります。10を比較してください77 必要なSHA256ハッシュの数は、天の川銀河(約1068)。
右-最初に、ここには非常に多くの質問があります。簡単に説明しますが、最初にリンクされている質問と passwords および- password-management タグ。あなたの質問の多くはそこで答えられています。実際、これらはすべて、暗号化キーを格納する場所に関する特定の質問を除きます。
簡単な要約:
パスワードは(HMAC + bcryptを使用して)ハッシュし、暗号化しないでください。ここに私が従ういくつかの一般的なルールがあります:
十分な時間制約を提供するアルゴリズム(つまり、bcrypt)を使用します。これは、bcryptを使用すると、各ハッシュの計算に必要な作業をカスタマイズできるため、攻撃者が実行できる総当たり攻撃の回数を減らすことができるためです。与えられた時間枠で。
ユーザーごとのソルトを使用します。ユーザーごとのソルトを使用することで、同じパスワードを持つユーザーが同じハッシュを持つことはありません。また、レインボーテーブルに関連するリスクも軽減されます。
データベースに保存されていないシステム全体のソルトを使用します。これにより、パスワードハッシュとソルトの両方が危険にさらされてDBが完全に侵害された場合に、セキュリティがさらに強化されます。メモリにのみ格納されている別のソルトを使用することにより、攻撃者は各ユーザーのパスワードを簡単に総当たりすることはできません。
はい、この問題については「何百もの」質問があります。これにより、私はその記事を書くように強いられました。
http://upokecenter.dreamhosters.com/articles/2012/02/secure-password-storage-for-web-sites/
基本的に、安全なパスワードの保存には以下が含まれます。
適切なアルゴリズム-bcrypt
またはPBKDF2
を使用します。どちらも、独自の「塩」でパスワードをハッシュする低速アルゴリズムです。暗号化は理想的ではありません。キーがわかっていれば正確なパスワードを回復できるため、必ずしもハッシュの場合とは限りません。 MD5、SHA-1なども、十分に「低速」ではないため、それ自体も理想的ではありません。
適切なパスワードポリシー-ユーザーに長いパスワードの使用を強制したり、強力なパスワードを奨励したりするなど。
その記事の改善に役立つコメントを追加してください。
まず最初に、常に 最小特権の原則 に従う必要があります。この場合は直接適用できませんが、絶対に元のパスワードが必要でない限り(リモート認証など)、使用しないことを意味します元のパスワードを取得できるようにするスキーム。
したがって、暗号化が考慮されるのは、元のパスワードを確実に取得する必要がある場合のみです。それ以外の場合は、パスワードのハッシュのみを保存します。
ハッシュスキームについては、パスワードのハッシュ/保存用に特別に設計されたものを使用する必要があります(例:crypt)。 MDやSHAファミリーなど)のような汎用の暗号ハッシュ関数に加えて、それらの多くは、総当たり攻撃を非効率的/困難にする追加の調整可能な時間コスト要因を追加します。
ブルートフォース攻撃といえば、ハッシュされたパスワードごとに固有のソルトを使用します。 cryptのような一部の パスワードスキームは、すでに自動ソルティングを適用しています 。それを使用し、独自のシステムを発明しようとしないでください。
データベースに保存されているパスワードをソルトでハッシュする必要があります。私は自分のパスワードハッシュライブラリを書こうとはしません。多くのPHPプロジェクト(私のものを含む))で使用される非常に人気のあるものはphpassです http://www.openwall.com/phpass/ -作成できますbcrypt、DES、またはMD5を使用したソルトハッシュ。
ユーザーがより安全なパスワードを作成できるようにするには、特定の長さまたは複雑なパスワードを作成するようにユーザーに要求できます。
パスワードのハッシュに使用する関数をすぐに提供できます(もちろん、キーはここで変更されます)。
$siteLongKey = '5efd8123878793f88bf1362905ae209794a8602f92969a67862b925fd6e50b04dfd31ae74002cb449824fcaa90e2efd096e8653a3f52e2b048e24b289c705129';
function hashPassword($password, $nonce = '') {
global $siteLongKey;
return hash_hmac('sha512', $password . $nonce, $siteLongKey);
}
これはかなり良いです。$ siteLongKeyはグローバルキーで、$ nonceは追加できるソルトです。メールアドレスやアカウントの作成日など、アカウントに関連する静的な情報を使用できます。この場合、ユーザーごとにソルトが異なります。これは一方向ハッシュであり、(理論的には)パスワードの回復はなく、パスワードのリセットのみです。