サーバーにランダムなシークレットkey
があり、それを使用して<id = random(), secret = hmac(id, key)>
資格情報タプルを生成し、これらの<id, secret>
タプルをクライアントに(安全な接続を介して)自由に渡したとします。
サーバーに向けられたメッセージを対称的に暗号化するためにsecret
を使用するクライアントに弱点はありますか?
例えば:
key
がロードされていますid
を生成しますsecret
とHMACing id
をkey
で生成します<id, secret>
タプルで(安全なチャネルを介して)応答しますM
を作成しますM
を対称的に暗号化し、そのsecret
をMAC化することによりM'
を生成します<id, M'>
タプルを送信します<id, M'>
タプルを受信しますsecret
をHMACing id
とkey
で導出しますsecret
を使用してM'
を認証および復号化します私にとって、これは、IDやシークレットを永続化する必要がないサーバーの利点を提供し、また(RSAキーペアの生成と比較して)高速です。
しかし、私はこのようにHMACを使用して秘密鍵を生成することの欠点を聞きたいと思っていますか?
私はこのスキームをグーグルで試しましたが、Google-fuは十分に強力ではありません( この質問と回答は少し近いようです 、しかしこれは適切な「キーの派生」ではありませんか?)。これが一般的ではない理由があるに違いありません。
また、これに名前はありますか?
HMACはそのようなキーを生成するための良い候補です。
少し掘り下げた後、「Algorithmically Generateing Symmetric Keys from One Base Secret」というテクニックを呼び出し、HMACの使用を特に推奨するこの本を見つけました:- https://www.safaribooksonline.com/library/view/secure-programming-cookbook/0596003943/ch04s11.html
[キーを作成するには]次のセクションで説明するように、ベースシークレットと利用可能な一意の情報を混合し、それらを擬似ランダム関数(PRF)に渡します。
彼らは後に「ユニークな情報」をdistinguisherと呼びます。ここでは、ランダムに生成されたid
と同じです。
さらに、ハッシュ関数を含む、PRFのいくつかの異なるオプションをリストします。
[...]一方向ハッシュは、多くの場合、PRFとして優れています。
ハッシュ関数をPRFとして使用するという考えを少し拡張します。
[...]ベースキーを一意のデータと連結し、文字列をSHA1に渡すことができます。
上記の引用は、原則として HMACの定義 に似ています。確かに著者はHMACを候補として具体的に引用しています:
潜在的に実用的な攻撃に抵抗する確実なソリューションを取得する最も簡単な方法は、カウンターモードでHMACを使用することです。
この引用は、ハッシュブロックサイズよりも長いキーを生成する場合のものです。カウンターモードは、キーデータを生成するときに、distinguisherに連続番号を追加することを意味します。カウンターの目的は、(長いキーを生成するための)出力ブロックの連結が単純に繰り返されないように、HMACの入力を一意に保つことです。
ここでは、secret
をハッシュブロックサイズよりも長くする必要がない限り、カウンターモードを使用する必要はありません。
著者の言葉で:
[生成された]キーが危険にさらされている場合、ベースシークレットを復元することは不可能です。
彼らはまた、追加の利点についても言及しています。
システム内の複数のエンティティは、適切なベースシークレットがあれば、同じ派生キーを計算できるはずです。