単一のパスワードを使用して、認証された暗号化メッセージを送信する必要があります。私は、ブロック暗号とHMACに同じ(派生した)鍵を再利用することはお勧めしません。
私の最初のアイデアは、暗号化してからMACスキームを適用するために、パスワードから2つの異なるキーを導出することです。
Key1 = PBKDF2(passwd、SALT1、ITERATIONS1)
Key2 = PBKDF2(passwd、SALT2、ITERATIONS2)
Mを平文とすると、送信されるメッセージは次のとおりです。
AES-CTRKey1(M)|| HMAC-SHA256キー2(AES-CTRKey1(M))
SALT1、SALT2、ITERATIONS1、ITERATIONS2、IV(カウンター)も付属。
このスキームに脆弱性はありますか?
私には良さそうですが、あなたの意見を知りたいのですが。
CCMモードのAES(CBC-MACを備えたカウンター)が代替手段であることを知っています。
ここにいくつかの弱点があります(最初のものが最も深刻です):
HMACへの入力に暗号化IVを含めない場合、攻撃者はIVを変更し、検出されずにメッセージに対応する変更を引き起こす可能性があります。同様に、攻撃者はSALT1またはITERATIONS1を変更する可能性があります。 HMACは依然として一致しますが、復号化するとジャンクになります。暗号化してからMACを使用する場合は、復号化に寄与するeverythingに対してMACを計算する必要があります。説明では、HMAC入力は、暗号化されたデータ自体を含む構造のエンコードである必要がありますが、IV、SALT1、ITERATIONS1、および使用されたアルゴリズムのシンボリック識別子も必要です(アルゴリズムの俊敏性を確保する場合) 。
PBKDF2は パスワードハッシュ関数 です。それは多くの反復でslowになっています。遅延は攻撃者と防御者に影響を与えるため、反復回数を任意に高く設定することはできません。説明では、防御側はtwoPBKDF2呼び出しを通常の使用法で使用する必要があるため、両方の料金を支払う必要があります。一方、攻撃者はどちらに対しても辞書攻撃を実行できます。したがって、防御側のコストはITERATIONS1 + ITERATIONS2ですが、攻撃側のコストは2つのうち小さい方です。これは攻撃者にとっての利点です。
PBKDF2はクラス最高ではありません。 GPUで非常に効率的に実行できます。 Bcryptの方が良いでしょう( この答え を参照)。
ソルト値に関しては、PBKDF2が一種の「ランダムOracle」のように動作することに依存しています。 PBKDF2の場合、これはもっともらしいことです(PBKDF2は、塩で始まるネストされたHMACのチェーンです)。ただし、これはあまり研究されていないプロパティであり、パスワードベースのキー導出スキームだけでは期待できません。セキュリティは精査に由来するものであり、アルゴリズムのエキゾチックな使用法は、定義上、暗号学者によって広範囲にレビューされていないため、意図したとおりに暗号プリミティブを使用する方が安全です。
より良いスキームは、oneパスワードハッシュ関数(たとえば、bcrypt)を1つのソルトと1つの反復カウントで実行します。そして、それはexpand結果を Key Derivation Function (速いもの、例えば [〜#〜] hkdf [〜# 〜] )暗号化キーとMACキーに分割する一連のバイトに。ちなみに、これはSSLでの処理方法です。急いでいて、追加のKDFを実装したくない場合は、多くの場合、単純なハッシュを使用できます。最初の128ビットは暗号化用で、残りの半分はMAC用です。
すべての一般性では、 認証された暗号化 を使用することをお勧めします。 CCMはAEモードでの初期の試みです。より良い選択は [〜#〜] eax [〜#〜] および [〜#〜] gcm [〜#〜] です。後者は急速にそのようなものの標準になりつつあり、NISTから恵まれてきました。 SSL/TLS(TLS-1.2以降)でサポートされており、一部の広範なライブラリ(OpenSSLなど)で使用できます。