34

S3 スタイルの認証を使用する RESTful APIでは、API クライアントは HMAC-SHA1 を使用して秘密鍵でリクエストに署名するため、秘密鍵がネットワーク経由で送信されることはありません。次に、サーバーは、クライアントの秘密鍵を使用して署名プロセス自体を繰り返し、その結果をクライアントから送信された署名と比較することにより、クライアントを認証します。

これはすべて良いことですが、サーバーがクライアントの共有シークレットの平文にアクセスする必要があることを意味します。これは、ユーザーのパスワードをデータベース内に平文で保存することに対するあらゆるアドバイスに反するものです。パスワードのソルトハッシュのみを保存することは、私が知る限りオプションではありません。クライアントの署名を検証できないためです。

私の API は RESTful であるため、ステートレスであるべきであることを強調しておく必要があります。他の API 呼び出しの前にログイン手順を実行することは避けたいと考えています。

オプションのソリューションの 1 つは、対称キー アルゴリズムを使用してすべてのユーザー パスワードを暗号化することです。ただし、サーバーはその暗号化のキーを、ソース コード内など、簡単にアクセスできる場所に保存する必要があります。これは何もないよりはましですが、最適な解決策ではありません (@Rook が回答で述べたように、CWE-257 に違反しています)。

ソリューションの別の方向性は、非対称署名に関する何かかもしれませんが、それを HMAC に適用する方法がわかりません。また、この件に関する記事も見つかりません。

ここで明らかな何かが欠けていますか?多くの立派なプロバイダーがこの種の認証スキームを実装しています。それらすべてが共通のセキュリティ原則に違反しているわけではありませんよね? そうでない場合、共有できるベスト プラクティスはありますか?

4

3 に答える 3

39

これは、対称キー チャレンジ/レスポンス スタイルの認証の欠点です。シークレットを送信する必要はありませんが、シークレットを両端に保存する必要があります。(HMAC は対称鍵システムです)。

ただし、これはパスワードではなく、共有シークレットであることに注意してください。ここには根本的な違いがあります。パスワードは一般にユーザーによって選択されますが、共有シークレットはランダムに生成されてユーザーに提供されます (このコンテキストでは、「API キー」と呼ばれることがよくあります)。

データベースが侵害された場合、攻撃者は他の場所で使用された可能性がある (そしておそらく使用された) パスワードを取得するため、パスワードを可逆形式で保存することは良くありません。一方、共有シークレットを保存することはそれほど問題ではありません。これはサービスに固有のシークレットであるため、攻撃者が取得できるのはサービスにログインする機能だけです。

一方、サーバー側でシークレットを保存する必要のない非対称システムを使用することもできます基本的な考え方は、サーバーがクライアントの公開鍵と現在のメッセージ シーケンス番号を知っているということです。API リクエストを送信するとき、クライアントはメッセージ シーケンス番号を増やし、シーケンス番号と API リクエスト パラメータに対して署名を計算します。これは、サーバーが公開鍵を使用して検証できます。古いメッセージ シーケンス番号が含まれている場合、サーバーはリプレイ攻撃を防ぐためにメッセージを拒否します。

于 2011-03-31T07:08:30.243 に答える
11

理想的には、ユーザーがログインした後、そのセッションの存続期間中、HMAC 秘密鍵 K として使用される暗号ナンスを提供します。これは安全なアプローチですが、REST はステートレスであるため、RESTful ではありません。ログインごとに発行されるメッセージ認証コードのこの考え方は、技術的には状態の形式です。

パスワードを暗号化してデータベースに保存することは、CWE-257に違反します。

于 2011-03-30T16:43:46.140 に答える
2

ここで何か不足しているかどうかはわかりませんが、1 つのオプションは、ハッシュされたパスワードを対称キーとして使用することです。

于 2013-04-05T09:01:16.107 に答える