.NETで最初のRESTAPIの開発を始めたところです。ステートレスになるため、認証にトークンを使用します。
基本的な考え方(System.Security.Cryptography):
- 暗号化のためのAES+整合性のためのHMACSHA256
- トークンデータは、ユーザー名、発行日、タイムアウトのプロパティを持つオブジェクトで構成されます
- データベースは、ユーザー名、ハッシュ化されたパスワード、およびHMACハッシュを保持します
ログイン:
- 資格情報が有効かどうかを確認します(ユーザー名、ハッシュされたパスワードをdb値と比較します)
- trueの場合、データオブジェクトを暗号化します
- 生成されたトークンでHMACを使用し、データベースに保存します
- トークン(HMACなし)をユーザー(cookie / string)に返します
認証が必要なメソッドへのリクエスト:
- ユーザーはリクエストごとにトークンを送信します
- トークンは復号化されます
- 有効期限が切れている場合、エラー
- 有効期限が切れていない場合は、HMACを使用して、ユーザー名+生成されたハッシュをdb値と比較します
- dbチェックが有効な場合、ユーザーは認証されます
私の見方では、このアプローチには次のような長所があります。
- dbが危険にさらされている場合でも、実際のトークンは含まれていません(ハッシュを元に戻すことはできません...)
- 攻撃者がトークンを持っていても、有効期限はトークン自体にあるため、フィールドを更新して有効期限を増やすことはできません。
さて、まず、これは良いアプローチかと思います。
それ以外に、AESキーとSHA256キーをサーバーのどこに保存するかがわかりませんでした(ハードコーディングするだけでいいですか?それらをweb.configに配置するか、マシンキーを使用すると、負荷分散サーバーの場合に問題が発生します。 ...)。
そして最後に、Crypto.CreateEncryptorは復号化のためにAES IVベクトルを必要とするので、どこにAES IVベクトルを保存しますか?ユーザーはリクエストごとにトークン+IVを送信する必要があるということですか?
これが理にかなっていることを願っています。事前に回答をありがとうございます。
アップデート:
さて、今私はさらにいくつかの調査を行い、この解決策を思いつきました:
- トークンには、最初に指定されたデータ(ユーザー名、発行日、タイムアウト)が含まれます
- トークンはencrypt-then-macで生成されます(HMACSHA265で生成された、AES暗号化データ、認証用のこれら2つの値のIVベクトル+タグが含まれます)
- トークンタグはdbに書き込まれます
- 次の場合、ユーザーは認証されます。
- タグは有効です(トークン認証)
- データを復号化できます
- トークンはまだ有効期限が切れていません
- タグはデータベースに書き込まれたものと一致します
- ユーザーがデータベースでブロックされていない(必要に応じてトークンの無効化)
- キーはweb.configの別のセクションに保存されます。同じキーがすべてのサーバーに存在する必要があります(もちろんアプリケーションごとに)
.NETには次の問題があるため、FormsAuthenticationTicketを使用しませんでした。
- 同じキーが異なる目的で使用されます(ビューステート、リソース、およびformauthticketsのmachinekey)
- .NETで使用されるmac-then-encryptは、encrypt-then-macほど安全であるとは見なされません。
- 有効期限が切れる前にトークンを無効にする組み込みの方法はありません