免責事項:私は独自の認証をロールすることの危険性について知っています。この例は、さまざまなハッシュ方法のデモで使用することを目的としています。
私はこのNode.js funcを作成してサーバー側を実行し、独自のロールを行わずに既存のlib(主にBcrypt)を使用する理由を強化しましたが、これが簡単に壊れる方法がわからないため、自分の引数を取り消す可能性があります。
私が想像できる唯一の方法は、おそらく既知のハッシュされたpwを取得し、ランダムなソルトを抽出し(長さを知る必要がある)、独自のレインボーテーブルを作成してクラックを試みることで、固定ソルト(コショウ)を計算できるかどうかです。固定塩(これは非常に長く、エントロピーが高い)。
function checkPw(pw, fullhash) {
//random one time salt is first 12 chars
var salt = fullhash.substr(0,12);
//hashing the full pw, our random salt, the pw and a global fixed salt
var hashpart = crypto.createHash('sha256').update(salt + pw + process.env.SALT).digest('hex');
return (hashpart === fullhash.substr(12));
};
私の質問は、ここの欠陥はどこですか?私が見逃している明らかなものがあるに違いありませんか?
いくつかの欠陥があります:
まず、なぜ「既存のlib(主にBcrypt)の使用を強化したい」のかわかりません。強固なパスワードハッシュアルゴリズムを使用するか(BCryptは適切です)、使用しないかのどちらかです。そうでない場合は、「強化」するのではなく、代わりに堅固なアルゴリズムに切り替えてください。
第二:あなたの言うとおり、あなたのコードはJavascriptです。 JavaScriptはクライアント側のハッシュを意味します。クライアント側のハッシングは気分が良いです。ここにsecurity.SEに いくつかの回答 があり、これがなぜそうなのかを説明しています。 (デモ目的でのみJavaScriptを使用する場合は、この点を無視してください。)
3番目:「固定塩」は、通常「 pepper 」として知られています。コショウは、いくつかの非常に特殊な場合にセキュリティを追加できます。コショウは秘密であることによって機能します。その結果、クライアント側のハッシュに使用しても、pepperには何のメリットもありません。
4番目:SHA256は汎用ハッシュです。高速になるように設計されています。 Fastは、パスワードハッシュに望まないものです。
5番目:最後の比較演算子はタイミング攻撃に対して脆弱です。
しかし、すべてが最初のポイントに帰着します。強固なパスワードハッシュアルゴリズム(BCrypt)を選択し、それを改善しようとしないでください。
誰かがデータベースを盗んだ場合、ソースコードも盗まれる可能性があります。そのため、彼らはハッシュスキーム、ソルトサイズ、ソルト位置を知っています。この情報を使用すると、データに対して辞書攻撃を行うことができます。
この関数の主な弱点はtimeです。比較的安価なリグを構築して、2つのGPUで1秒あたり数十億の組み合わせをブルートフォースにすることができます。 bcryptを使用すると、使用するハッシュラウンドの量を定義できます。 1000ラウンドのbcryptは、解読するのに約1000倍高価です。