「if password == XXXXXXX」は最低限のセキュリティに十分ですか?


20

セキュリティリスクが中〜低のアプリ(つまり、バンキングアプリなどではない)のログインを作成する場合、ユーザーが入力したパスワードを次のように入力するだけで検証できますか。

if(enteredPassword == verifiedPassword)
     SendToRestrictedArea();
else
     DisplayPasswordUnknownMessage();

効果的であるように簡単に思えますが、それが必要なすべてであるかどうか私は確かに気にしません。ユーザー名とパスワードのコンボを簡単にチェックするだけで十分ですか?

更新:特定のプロジェクトはたまたまWebサービスであり、検証は完全にサーバー側であり、オープンソースではありません。ドメインは、これに対処する方法を変更しますか?


3
それはvalidPasswordがどこから来たのでしょうか?ハードコードされている場合、コードを変更せずにパスワードを構成/変更することはできません。構成ファイルから取得した場合、そのファイルにアクセスするすべてのユーザーに表示されます。
アルプ

1
「ユーザー名とパスワードの組み合わせのチェックは十分ですか」
クリス

3
@意見:これはログインしていないよりも悪いとは考えにくい。このような強い主張の理由をいくつか説明してください。
モーガンハーロッカー

1
パスワードを検証してパスワードを比較しているときに、有効であることを確認していない場合、用語は間違っています。 違いを理解するために時間をかけてください。
billy.bob

1
これは、プレーンテキストのパスワード保存を意味し、これは無責任です。また、パスワードが間違っていることをユーザーに警告することを意味し、潜在的な攻撃者に多くの情報を提供します。「ログインまたはパスワードが正しくありません」など、常に曖昧でなければなりません。
ラインヘンリヒス

回答:


26

SSLなしではない

パスワードがプレーンテキストでネットワーク経由で送信される場合、これは安全ではありません。パスワードがプレーンテキストでネットワーク経由で送信される場合、サーバー側でのパスワードのハッシュも安全ではありません。

HTML <input type="password"/>タグの内容はプレーンテキストで送信されるため、WebサイトでSSLを使用してパスワードを送信しない限り、サーバーにパスワードを保存する方法に関係なく、これは問題になります。

(ブラウザでパスワードを要求するダイアログボックスを表示するHTTP認証は、サーバーとブラウザに共通の認証メカニズムに応じて、クリアテキストである場合とそうでない場合があります。 SSL。)

サイト管理者が疑わしい場合ではない

ここで、Webサイトの実行にHTTPSを使用していると仮定すると、サイト管理者(プレーンテキストのパスワードを読み取ることができる)およびマシンにアクセスできる他の人が正しく動作することを信頼する場合、これは安全です。今、彼らはあなたのウェブサイトで彼らが望むことを何でもできることは明らかかもしれません(彼らはそれを管理しているので)が、彼らがパスワードを読むことができれば、他の人のサイトで盗まれたログイン/パスワードのペアを使用することもできるかもしれません。

パスワードを管理者から安全に保つ方法

パスワードを保存および確認する安全な方法の1つは次のとおりです。

def change_password user, new_password
  salt = random(65536).to_s(16) #will be 4 characters long
  password_hash = salt + hash(salt + new_password)
  store(user,password_hash)
end

def does_password_match? user, entered_password
  correct_password_hash = retrieve(user)
  salt = correct_password_hash[0...4]
  entered_password_hash = salt + hash(salt + entered_password)
  return correct_password_hash == entered_password_hash
end

ハッシュ関数には、強力なものと、まだ良いレインボーテーブルを持たないものを使用してみてください。必要に応じて、レインボーテーブルを回避してソルトの長さを変更できます。

使用している環境、ネットワークレイテンシの変動、およびユーザー名が一般に知られているかどうかhash('0000'+entered_password)に応じて、攻撃者からの攻撃を防ぐために、ユーザーが存在しない場合は別のコードパスを計算することができますかかった時間に基づいて有効なユーザー名を判別すると、パスワードが正しくないと判断されます。


1
良いアドバイス:) SSLに関しては、実際に動作するものを設計する必要があり、単純に非対称暗号を使用してパスワードをエンコードし(Javascriptが必要)、サーバーでデコードします。その後、塩+ハッシュが正常に発生します。また、公開鍵はWebページとともに送信されるため、頻繁に任意に変更できます。
マチューM.

1
@Matthieu M .:誰かがあなたのWebページを偽造できる場合、彼は公開鍵を自分自身が対応する秘密鍵を知っているものに変更することもできます。したがって、あなたのアイデアは、中間者に対してではなく、受動的な読み取り攻撃に対してのみ役立ちます。
パエロエベルマン

@Paulo:はい、SSLは暗号化だけでなく証明書についても同意しますが、残念ながらここではショットを呼び出しません。人々が通常のhttp://接続でウェブページを使用したいと言ったとき... /
Matthieu M.

@Matthieu:public_keyを公開Webページの一部として送信encrypt(entered_password, public_key)し、クライアントで計算し、その結果をサーバーに送信するという意味does_password_match?(user, decrypt(encrypted_password, private_key))ですか?
ケンブルーム

@Ken:多かれ少なかれ、あなたは暗号化の権利を手に入れました。パスワードを一致させるにはmore does_password_match(user, salt, decrypt(encrypted, key))で、ユーザーに応じてソルトを使用します。私が言ったように、明らかな問題は中間者保護の欠如です。
マチューM.

52

これは、パスワードをオープンテキストで保持していることを示唆しています。これは、セキュリティの低いシナリオであっても、まったく問題ありません。

あなたはむしろ持っているべきです:

if(hash(enteredPassword) == storedHash)

MD5などの単純なハッシュを使用できます


22
パスワードをハッシュするための+1。しかし、少なくとも塩も追加したいと思います。そうしないと、ユーザーはシステム間でユーザー名とパスワードを再利用するため、セキュリティの低いアプリに違反すると、攻撃者がセキュリティの高いアプリに違反する可能性があります。たとえば、最近のHBGaryハックは、Webサイトを実行しているCMSシステムを侵害し、サーバーへのルートアクセスに変えました。これは、低セキュリティCMSシステムがハッシュに塩を追加していなかったためですarstechnica.com/tech-policy/ニュース/ 2011/02 /…
ジャスティンケーブ

1
同意します...次のことを考慮してください。「strings JavaFile.class | grep -i password」
法案

パスワードを一度だけ使用する場合、パスワードをプレーンテキストで保持することの問題点

10
@Timは、ユーザーパスワードを1回し使用しないためです。調査は一貫して、ユーザーが何度言われてもパスワードを複数回再利用することを示しています(例:theregister.co.uk/2011/02/10/password_re_use_study)。
スコット

3
@Tim:さらに、テキストエディタでexe、dllなどを開くだけで、パスワードがすぐに表示されます。
ガスカバルカンティ

14

私はハッシュを提案する人々に同意しますが、ここであなたが再発明している車輪もあります。プラットフォームによっては、ユーザーの介入をあまり必要とせずに、すべてのユーザー管理を安全かつ確実にカバーする役割/ユーザー管理ツールを見つけることができます。


ASP.Netメンバーシッププロバイダーを発見したばかりですが、「このようなものを実装するのに何回時間を無駄にしましたか」と考えていました。
グレナトロン

8

特にユーザーの不便さと情報の安全性のバランスを取る必要があるため、セキュリティは非常に扱いにくいテーマです。通常、必要なセキュリティの量の式は、データの重要性の関数です。要するに:

isSecuritySufficient = effortToBreak > rewardForBreaking

悪いことをする人についてよくある誤解は、彼らが何を求めているかです。それらのほとんどは信頼を破壊しようとしています。ユーザーの信頼を守るために、できる限りのことを常に行う必要があります。その一部は、彼らの身元が安全であることを確認するためにデューデリジェンスを行うことです。格納するデータについてはあまり気にかけないかもしれませんが、セキュリティの最低のしきい値であっても、身元については気にします。

多数の低コスト(実装してユーザーに影響を与えるため)のオプションが利用可能です。そのうちの1つは、最低限パスワードをハッシュすることです。パスワードと同じくらい機密性の高いものをプレーンテキストで保存するサービスは、ハッキングされるのは恥ずべきことです。

パスワード保護の一般原則

  • パスワードをプレーンテキストで保存しない
  • SHA-1やSHA-512などの安全なハッシュ関数を使用したハッシュ(MD5でも一致するハッシュを見つけるのは簡単すぎます)
  • アプリケーションのソルト値を使用します。ソルトは、推測しにくいようにパスワードに追加されるランダムなバイトです。実行時にソルトを生成し、マシンに関する情報をシード値として使用して、何らかの方法で保存および参照する必要があります。
  • ユーザー固有のソルト値を使用します。これをアプリケーションソルトと組み合わせて使用​​します。
  • ネットワークを経由するすべての認証要求を暗号化します。つまり、WebアプリケーションにSSLを使用します。

認証にSSLを使用するため、少なくともユーザーのアカウントを扱うすべてのページも暗号化する必要があります。これにより、ユーザーのIDを可能な限り保護できます。

パスワード管理に関する注意:ユーザーは時々パスワードを忘れます。絶対に最悪のことは、パスワードをメールで送信することです。上記の原則を実装する場合、とにかくそれを行うことはできません。登録済みのメールアドレスに送信されたリンクを使用してパスワードをリセットする方法を提供することをお勧めします。そのリセットリンクには、ページにアクセスする人が彼らであることを保証するための1回限りの使用コードがあります。


1
最初は、アプリケーションソルト+ユーザーソルトのアイデアに本当に感動しましたが、考えれば考えるほど、私は確信が持てなくなります。たとえば、アプリケーションソルトの4文字とユーザーソルトの4文字を使用した場合、そのソルトとユーザーソルトの8文字の違いは、ソルトの半分がすべてのユーザーで同じになるということです。アプリケーションソルトを使用するよりも、ユーザーソルトのサイズを大きくする方が安全だと思われます。また、アプリケーションソルトがハードウェアに基づいている場合、すべてのパスワードを無効にせずにハードウェアをアップグレードまたは変更することはできません。
デヴィッドコンラッド

問題は、ユーザーsaltがユーザーパスワードと共にデータベース行に含まれていることです。悪い人が塩の目的を知っている(そして彼らがしている)場合、彼らはそれをデータベースで見れば、彼らはそれを完全にクラックする方法を知っています。計算ではなく、計算される部分をアプリケーションに含めることで(毎回同じ方法で)、ユーザーテーブルをクラックすることがはるかに難しくなります。もちろん、さらに一歩進んで、1部の純粋なランダムソルトと1部の計算されたソルトを作成できます。両方ともユーザー固有です。
ベリンロリチュ

ああ、私は、データベースの塩の一部を保管します。それは理にかなっています。ありがとうございました。
デビッドコンラッド

行ごとに一意である限り、行ごとに塩を保存する問題はありません。ここにハッシュがあります: "fd84235a55bbfeb1585a3dd069d48127989c9753058b51b6ba2056fd6c5a0a91"(SHA256)、ここに塩: "671254bdf7944f8fa88e6c9913b948ee"。パスワードを取得できると思いますか?その塩のための虹のテーブルはありません(たとえ塩を与えられたとしても)、あなたはそれを強引に固執しています。
ブライアンベッチャー

3

パスワードが他に使用されない限り、それは問題ありません。ユーザーがパスワードを再利用できると判断するリスクは依然として存在するため、次の場合にはさらに改善されます。

if(hash(enteredPassword) == hashOfValidPassword)

自分自身またはパスワードがプレーンテキストで保存されていることを知っている人向けの場合は、問題ありません。


1
vartecの答えに対するJustin Caveのコメントのように、saltを使用しますif (hash (enteredPassword + salt) == hashOfValidSaltedPassword)-そして、これ+はおそらく追加ではなく連結であることに注意してください。これは、可能性のあるパスワードのハッシュのテーブルであるレインボーテーブルの使用を本当に妨げています。
デビッドソーンリー

確認しているのがハッシュだけである場合、保存されたハッシュと同じハッシュを生成するまで、可能な文字列のループを単に実行することはできませんか?結局、同じハッシュに対応できる文字列がたくさんあります。
モーガンハーロッカー

@Prof Plum:ハッシュアルゴリズムが優れている場合、衝突を見つけることは非常に困難です。これが現代の暗号化の基礎です。これらは本質的に一方向の機能です。

3

ソースコードは利用可能ですか?そうでなくても、バイナリが利用可能な場合は、マシンの指示でパスワードを見つけることができると確信しています。代わりにチェックサムを実行して比較することをお勧めします。

あなたの意見ではセキュリティがそれほど重要ではない場合でも、セキュリティを見落とさないでください。


2
はい、オープンソースプロジェクトの場合は悪い考えです:)

-1-ソースがあると違いがあると思う場合、セキュリティについては何も知りません。
-mattnz

1

絶対違う。読んだ本を、それはハッカーがセキュリティのウェブサイトをハッキングする方法について説明します。あなたは、チェーンの中で最も弱いリンクとしてあなたを持っているでしょう。


0

いくつかの回答で、パスワード自体を保存するのではなく、ハッシュを保存する必要があることが指摘されています。SSLを使用する必要があります。

あなたは言うかもしれません、大したことは何ですか?私のアプリケーションがハッキングされたとしても、それはほとんど問題になりません。まあ、ユーザーがすべてのサイトで同じパスワードを再利用することは非常に一般的なパターンです。サイトをハッキングしてユーザーのパスワードにアクセスするハッカーだった場合、ハッカーはそれらのユーザーにとってより重要な他のサイトで多くのユーザーになりすますことができます。そのため、サイトをハッキングすることは、ハッカーがユーザーの銀行情報アクセスするための最初のステップになる可能性があります。

そして、パスワードをハッシュするだけでは十分ではありません。塩でハッシュする必要があります。ハッカーは逆ハッシュルックアップテーブルを持っているため、特定のハッシュに対して、一致するパスワードを見つけることができます。

これらの機能を実装しないことを選択した場合は、このセキュリティの欠如をユーザーに通知し、他の場所で使用するのと同じパスワードを使用しないように奨励する必要があります。


-2

これがサーバー側である限り。

もう少しセキュリティが必要な場合は、httpsを使用し、DBでパスワードを暗号化\ハッシュします。


3
これがWebアプリであると仮定する理由
クリス

いい視点ね!今やりました。
モロンズ

4
-1サーバー側であっても、これはまだ大丈夫ではありません。
GSto
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.