これらのどれがより安全であるのだろうか。
次のように、ハードコードされた資格情報を想像してください。
if user.Equals("registereduser") && (password.Equals(encryptedpassword))
{
Give access to the user
この方法には、新しいユーザーを追加するたびにコードを変更する必要があり、アプリケーションを使用している数人だけが使用できるという大きな欠点があることは知っています。しかし、あなたがそれを使用するためにたくさんの人々を持つつもりであるとわかっていて、それがほとんど変わらないなら、それはそれほど恐ろしいことではありません。
コンパイルされたコードを妥当な時間内に逆コンパイルすることは不可能であり、攻撃者は最初からハードコードされたパスワードを探すつもりはないと思います。
このような資格情報をハードコードする方が安全ですか?または、データベースでパスワードを暗号化する一般的な方法を使用する方が安全ですか?
いくつかのポイント:
DBでパスワードを暗号化するということは、ハッシュです。それは大きな大きな違いです。
ユーザーデータをハードコーディングする代わりにDBが使用される最初の理由は、セキュリティではなく単純さです。
(ユーザーの追加/変更/削除なし再コンパイルなど)
パスワードをプレーンテキストで保存することは問題です。パスワードがプログラムにあるかDBにあるかは関係ありません。ハッシュ化してソルトを付けて保存します(DBやプログラムは関係ありません。ハッシュ化してください)。
攻撃者がユーザーデータがプログラムに存在することを期待しないことを信頼することは、「あいまいさによるセキュリティ」であり、通常はnot安全です。
コンパイルされたプログラムから文字列を取得することは、思ったよりはるかに簡単です。例のような難読化がなければ、1分もかかりません(これには、エディターの起動と文字列の手動検索が含まれます)。そして、あなたのプログラムはまったくコンパイルされていると誰が言っていますか?例えば。 PHP ...
その背後にある理由がわからない場合は、確立されたプラクティスを変更しないでください。
資格情報やハッシュをハードコードしないでください。
ハードコードされたパスワードは、簡単に修正できない方法でシステムのセキュリティを危険にさらす場合があります。 [...]また、問題の修正も非常に困難になります。
[...]多くのハッシュは元に戻すことができます(または少なくともブルートフォース攻撃に対して脆弱です)。さらに、多くの認証プロトコルはハッシュ自体を要求するだけです[...]
ユーザー名、パスワード、証明書、トークンID、電話番号などの資格情報をソースコードに含めないでください。
データベースがDMZに配置されていないが、代わりにWebサーバーから直接アクセスでき、アカウントの権限が制限されている)理想的な世界では、データベースに違反し、ハッシュ化されたパスワードテーブル、私はしなければなりません:
プログラムのアカウントを使用してテーブルを直接読み取ることができない場合は、dbサーバーの管理者アカウントを危険にさらすか、またはdbサーバーのVMを完全に危険にさらすことができない限り、基本的には完了です。
そして、これはあなた自身のハッシュスキームが安全かどうかの質問に入る前にすべてです。
ユーザー名とハッシュが「隠されている」という点では、コンパイルされたコードを使用しても、それらは単に隠されていません。ユーザー名のようなものは、16進エディターを使用したクイックパススルーでもすぐに明らかになります。
ネットワーク経由で必要な手順は次のとおりです。
それでおしまい。 Webサーバーに咳が出て、コードビハインドファイルを直接プルダウンできる場合は、これで完了です。私はそれをもたらす可能性のあるものよりもWebサーバーの詳細な妥協は必要ありません(他の方法ではWeb読み取り可能なディレクトリにあるかどうかによって異なります)。または、コードに脆弱性を見つけた場合、格納されているユーザー名とハッシュを直接吐き出す可能性があります。そしてもちろん、Webサーバーが完全に危険にさらされる可能性もあります。
このように攻撃ベクトルを減速させる方法はありません。特定のレベルの違反が他のレベルに到達する前に検出したと仮定すると、1つの違反がすぐにすべてを露呈します。コンパイルされたソフトウェアについて話している場合でも、熟練した攻撃者はハッシュアルゴリズムだけでなく、使用している場合はコショウも知っており、ハッシュ化およびソルト化されたパスワードテーブルに効果的にアクセスできます。
2番目の原則をより簡単に説明すると、ソフトウェア自体は、実際に実際に特定のユーザーの保存されたパスワードを直接知る必要はありません。それらを認証します。与えられたパスワードが保存されているパスワードと同じであるかどうかを知る必要があるだけです。これは、ソフトウェアが使用している資格情報がデータベースに悪意を持ってアクセスするのを防ぐ方法で、データベースがパスワードを決定できるものです(ソフトウェアで利用できるようになったストアドプロシージャからブルートフォースをしようとする以上に、おそらく試行回数と速度に基づいて検出してシャットダウンします)。
他に選択肢がない場合を除いて、独自の認証をロールバックしないでください。または、実行しようとしているすべての背後にあるすべての理論的根拠が実際にわかっており、おそらく自分よりも多くの優れたレビューを行っている努力を複製する意思があると確信しているあなたのものを通過させます。それはあなたの時間の価値がありません、そしてそれはほとんど常に常に確立されたライブラリまたはパッケージよりも安全でない何かをもたらします。
業界標準のプラクティスとは異なる何かをすることで賢くなっていると思われる場合は、それらのプラクティスの背後に実際に非常に良い理由があるかどうかについて、非常に長く、真剣に考えてください。
ユーザーの資格情報が他の誰かの手に渡ったら、たとえそれらをハッシュしたとしても、たとえ自分が何をしていてそれらをハッシュしたとしてもwellこれは、人々が転がろうとする場合はめったにありません独自のセキュリティ—が侵害されていると想定する必要があります。それは本当に 時間の問題のみ です。最善のハッシュ作業は、パスワードがリセットされるまでユーザーに通知し、アカウントをロックするためのウィンドウがあるせいぜい遅延です。
ここで私が見るもう1つの問題は、セキュリティにも関連しています。ユーザーの1人がキーロガーやフィッシング攻撃に感染したためにパスワードを変更する必要があるとします。どのようにしてそれを行うことができますか?あなたにできる唯一の方法は、彼らに彼らのパスワードを尋ね、そのパスワードを再ハッシュし、それをあなたのコードでそれを置き換え、再コンパイルし、そして再公開することです。それはあなたがしなければならない多くの「再」です。データベースを使用する場合は、「パスワードの変更」ページを1つ作成して、データベースにフックするだけです。できました。