私はあなたの設計と要件について確信が持てないので、これのいくつかはベースから外れているかもしれません。うまくいけば、それのいくつかも役に立ちます。
まず、攻撃を理解するのに少し苦労しています。私はおそらく何かが欠けているだけです。Alice は、カウンタ、ペイロード、および (counter||payload) の HMAC を含むメッセージを Bob に送信します。Eve はメッセージを傍受して再生します。ボブはそれを見たので、それを捨てます。Eve はカウンター + 1 を使用して新しいメッセージを計算しようとしますが、このメッセージの HMAC を計算できず (カウンターが異なるため)、Bob はそれを破棄します。利用可能なシークレットがある限り、Eve はメッセージを偽造することはできず、メッセージを再生しても何も起こりません。
では、「既知の秘密鍵」とは何でしょう? このキーは攻撃者に知られていますか? (もしそうなら、彼は簡単にメッセージを偽造できるので、HMAC は役に立ちません。) あなたは DH を持っていることに気付いたので、それを使って鍵をネゴシエートしますか?
あなたの質問の残りの部分を考えて、私が攻撃を見逃していると仮定すると、共有秘密がある場合は、それを使用してメッセージ、または少なくとも時間+カウンターを暗号化してみませんか? 時間とカウンターを一緒に暗号化することにより、レインボー テーブルは実用的ではなくなります。
共有シークレットがあるが、暗号化に使用できるプロセッサがない場合でも、MD5(secret+counter) のようなことを実行して、攻撃者が先を推測するのを防ぐことができます (HMAC-MD5 用に MD5 が既に使用可能である必要があります)。 .
以前、共有シークレットも DH も使用せずにこの問題に取り組みました。その場合、組み込みデバイスにはデバイスごとの公開/秘密鍵ペアが必要でした (理想的には製造時にインストールされますが、最初の電源投入時に計算され、不揮発性メモリに保存されます。ランダム性は困難です。1 つのオプションは、サーバーに提供させることです)。乱数サービス; シリアル番号のような固有の非公開情報がチップ上にある場合は、それを使用してキーをシードすることもできます. 最悪の場合、MAC と時間に加えて、ネットワークからおねだりできるエントロピー。)
HMAC を使用するのではなく、公開/秘密鍵を配置すると、デバイスはメッセージに署名するだけで、最初のメッセージで公開鍵をサーバーに送信します。公開鍵は、デバイスの識別子になります。このアプローチの良いところは、交渉フェーズがないことです。デバイスは話し始めることができ、サーバーがこの公開鍵を聞いたことがない場合は、新しいレコードを作成します。
ここには、攻撃者がデータベースをジャンクでいっぱいにする可能性があるため、小さなサービス拒否の問題があります。これに対する最善の解決策は、製造中にキーを生成し、すぐに公開キーをデータベースに挿入することです。これは、一部の契約製造業者にとっては非現実的です。そのため、デバイスが初めてサーバーに対して自身を認証するために使用できる共有シークレットを含めることに頼ることができます。これは弱いですが、ほとんどの場合、おそらく十分です。