典型的なハッシュと比較して RFC2898DeriveBytes を使用するのはいつが適切ですか?
更新
KDFは通常、ストリームの暗号化に使用できる対称キーを作成するために使用されることを理解しました。また、PBKDF2が廃止されたことも理解しました PasswordDeriveBytes 。この質問の目的は、ハッシュされたパスワードを保存する強力な方法としてKDFを転用する可能性を探ることです。暗号化しようとしているコンテンツは、人間が覚えてコンピューターに入力できるUnicode文字列です。
KDFに興味があるのは、
質問
通常のハッシュ法とは対照的に、この方法でKDFを使用することに対する/反対の議論は何ですか? (免責事項:通常のハッシュ方法とはですか?)
NISTはPBKDF2を承認します パスワードをハッシュおよび保存する場合。ただし、これは本来の目的ではありません。特に、 StackExchangeもPBKDF2を使用 は同じ目的で使用します。 ソースコードはこちらから入手できます。
BCryptとPBKDF2の比較については、 この回答 を参照してください。 BCryptは、パスワードを保存するより一般的な方法です。
PBKDF2は.NETに組み込まれており、すでにFIPSに準拠している)ため、私はPBKDF2を検討しています。
PasswordDeriveBytes
は、PBKDF1キー派生関数を実装します。 KDFは、秘密データ(ここでは「パスワード」、つまり人間の脳に収まり、人間の指で入力できる種類のデータ)を、アルゴリズムを必要とするアルゴリズムに適したビットシーケンスに変換する関数です。対称鍵(例:対称暗号化)。 KDFは、特にパスワードの保存など、他の目的には使用できません。
必要な対称鍵がハッシュ関数の出力サイズ以下である場合、ハッシュ関数をKDFとして使用できます。ただし、このようなKDFは非常に粗雑です。優れたKDFが提供する機能の1つは、十分に遅いことです。これは、「パスワード」は本質的に徹底的な検索に対して脆弱です(「辞書攻撃」とも呼ばれます。ユーザーは、数百万または数十億回の試行で推測できる単純な単語または組み合わせではなく、パスワードとして選択する傾向があります)。特定のシステムでは、通常、比較的遅いKDFを許容できます。認証しようとするユーザーには、キー派生関数の1µsと1msの遅延の違いは見られません。しかし、1000倍のスローダウンは攻撃者にとって致命的です。1日の破壊的な労力を3-年の破壊的な労力に変換します。
PBKDF1には、「反復カウント」が含まれています。これは、まさにそのためのパラメーターです。構成可能な方法で、鍵の導出を適切に遅くします。単純なハッシュ関数は、そのためには速すぎます。 KDFとしての使用法は、ハッシュ関数よりもPBKDF1を優先する場所です。実際、PBKDF1は推奨されません。 同じ標準 のPBKDF2は、より堅牢であると想定されています。
ハッシュ関数はKDFよりもはるかに汎用的なオブジェクトであり、KDFが満たさない他の多くの使用法があります。
何をしたいのかがはっきりしていません。RSAまたはECDSAのように、通常「非対称デジタル署名」を意味する「署名」という用語を使用します。 [〜#〜] mac [〜#〜] のように、対称性の整合性チェックを指定するために「シグネチャ」という用語を使用する傾向がある人がいます(「シグネチャ」と呼ぶのは不適切です) 、しかし広まっています)。ただし、これにはある時点でいくつかの秘密が必要であり、キーがあり、ハッシュ関数にはキーがありません。
私が何かを見逃していない限り、PasswordDeriveBytesおよびその他のPBKDF実装は、パスワードを格納することを目的としておらず、「典型的な」ハッシュの代わりに使用されることもありません。
これは、ユーザーが指定したパスワードに基づいて、対称暗号化のための暗号化キーを作成することを目的としています。
明確にするために、次の状況を考慮してください。
ファイルの暗号化を必要とするアプリケーションがあります。これはユーザーの裁量で行われ、ユーザーの選択で復号化できます。
ああ、MS Wordにはその内容を暗号化する機能があるとしましょう。または、暗号化されたZipファイル。
ユーザーにアクセスを許可するが、ユーザーに強力でランダムな正確に256ビットのキーの生成を任せたくないため、覚えにくい等.
そのため、ユーザーが必要な任意のパスワードを設定することをユーザーに許可し、そして派生そこからの暗号化キー.
パスワードを保存したり、単純なハッシュを使用して保存したりすることは決してありません。キーマテリアルを作成することのみを目的としています。
PBKDF2は RFC 2898 10年前に廃止されたPBKDF1よりも優れています。 Rfc2898DeriveBytes Class(System.Security.Cryptography) で.NET用に実装されています
Java 6の時点で、SunJCEにPBKDF2の実装:PBKDF2WithHmacSHA1があることもわかります。
以前のバージョンのJavaの場合 BlackBerry App Security-Stack Overflow で説明されているように、PBKDF2の実装は A free Java RFC 2898/PKCS#5 PBKDF2
ただし、SHA-256を使用するほうが、現在非推奨となっているSHA-1よりも優れているのでしょうか。
重要な反復カウントでRFC2898DeriveBytesを使用する方が、認証目的でストレートハッシュ関数を使用するよりも優れているはずです。
まず、ソルトを入れる必要があります。開発者がソルトをハードコードするような愚かなことをすることはまだ可能ですが、開発者が通常ソルトではないすべてのものを混乱させる場所よりも少なくとも1歩は近づきます。ソルトを使用するだけで、レインボーテーブルがすでに存在する可能性が低くなり、誰かの平凡なパスワードが機能するようになります。各ユーザーに対してランダムにソルトを使用すると、複数のユーザーが同じパスワードを使用している場合に情報の漏えいが停止し、簡単なパスワードが非常に難しくなります。各ソルトのテーブルを生成する必要があるため、取得してください。
2つ目はRFC2898DeriveBytesでは残念ながらハッシュ関数を選択できず、HMAC-SHA1を使用していて、PBKDF1と比較した場合の良い点は、キーのサイズが実際に必要な大きさになる可能性があることです。つまり、標準のハッシュアルゴリズムと比較して、Rainbowテーブルの格納と配布を困難にするのに役立ちます。
最後に、反復回数が重要です。ハッシュ計算が遅くなるほど本当に数が多い場合、標準のハッシュアルゴリズムは高速になるように設計されており、データストレージは指数関数的に増加しているため、キーのサイズだけに頼ることはできません。
OPの質問とその質問の目的は、多少矛盾しています。誰もが指摘しているように、PBKDF2は主にパスワードenc /ストレージではなく、キーの生成に使用されます。最も一般的には、WPA2 PMKおよびその他のWPAキー生成スキームで使用されます。たとえば、パスワード+ SSID名とSSID名の長さの塩などのコンポーネントの例を使用します。 4096回の反復SHA1ハッシュ。
パスを暗号化する場合、セキュリティのために最も重要なことは、長さと動的でユーザーに透過的でないソルトです(つまり、悪用者はソルトを特定できません)。最小20文字のパスワード、ランダムなソルト、SHA-256の4K +の反復(PBKDF2はその目的のためにSHA1の少なくとも1Kの反復を推奨)でAES暗号化ストアを使用する場合、ハッカーは非常に困難な時間を費やすことになりますそのパスワード(参照:数年または数十年で桁違いの桁).
また、パスワードの暗号化は最終用途(速度、セキュリティレベルの必要性など)に大きく依存しているため、最終用途の可能性を知らないと、理想的なソリューションを推奨することが難しくなります。