OAuth 2.0フローを実装するサービスを実行していて、エンドユーザーがサードパーティのアプリにログインできるようにし、それらのアプリがいくつかのAPIを介してサービスのデータを消費することを許可しているとします。
OAuthフローを介してサードパーティアプリを正常に認証すると、サービスはサードパーティアプリに(代理として)サードパーティアプリを認証(および承認)するベアラートークンを送信しますエンドユーザー)がサービスのAPIを使用します。
着信API呼び出しの認証を実行するには、このようなベアラートークンをサーバーに保存する必要があります。署名なしトークンはクライアントを認証(および承認)するため、パスワードを保存する場合と同様に、安全に保存する必要があります。
ただし、パスワードはソルト+ハッシュされてからディスクに保存されますが、パスワードの安全な表現ではなく、対応するプリンシパル(ユーザー名/メールアドレス)によっても検索されます。
ベアラートークンの場合、一致する資格情報/トークンを検索するために使用するプリンシパルはありません。パスワード(ソルト+ハッシュ)などのベアラートークンを保存する場合は、考えられるソルトをすべて検索して適用し、ソルトトークンをハッシュして、システム内に存在するかどうかを確認する必要があります。それはスケーリングしません。
だから私の質問は:ベアラートークンをサーバーに安全に保存するにはどうすればよいですか?つまり、トークンを検証する必要があるときは常に、可能なすべての安全な表現を生成する必要はありません。
「ベアラートークンを安全に保存する」とは、「安全に保存された」すべてのベアラートークンのファイルを取得した攻撃者がそれらを使用できないことを意味します。
サードパーティからOAuthプロバイダーへのリクエストに、ユーザーの名前やIDなど、ユーザーにリクエストを関連付けるその他のデータがある場合、サーバーは通常のパスワードのように無記名トークンを保存できます個別のソルトを使用します。ただし、サードパーティのリクエストに識別可能な情報がない場合、サーバーはソルト+ハッシュバージョンのベアラートークンを、すべてのベアラートークンの共有ソルトとともに保存できます。OAuthトークンはすぐに期限切れになります。一意のソルトは、期限切れになることのないパスワードに比べてそれほど重要ではありません。トークンが6〜12時間後に期限切れになると、攻撃者はハッシュを現実的にクラックしてユーザーにアクセスできなくなります。その後、サーバーは、セキュリティを強化するために、毎週など定期的にソルトをローテーションさせることができます。
ジャスティンの答え に基づいて、私は自分で構築しています。
トークンが十分に長い場合(私の場合は200文字の英数字([A-Za-z0-9]
)である場合)、トークンをソルトする必要はありません。複雑さは十分に高いため、ハッシュだけで十分です。
トークンがハッシュだけで済むのに十分な長さでない場合(またはそれらをソルトすることも主張したい場合)、トークン生成スキームをわずかに変更できます。ランダムトークンを生成する代わりに、トークン固有のプリンシパルも生成します。次に、2つを連結し、結果を1つのトークンとしてコンシューマーアプリに渡します。これは基本的にAPIクライアントにユーザー識別情報も送信するように要求しますが、便利なことに単一のトークンに埋め込まれています。
内部的には、保存する前に実際のトークンをソルト+ハッシュし、トークン固有のプリンシパルを個別に保存します。トークンの検証に関しては、送信されたトークンを2つに分割し、実際のトークンとトークン固有のプリンシパルを取得します。その後、このプリンシパルを使用して、マッチャーを実行できるsalted + hashed実際のトークンを検索できます。
具体的な例:
a0z9B1Y8c2x7
D3W6e4v5F5
aabbccddeeff00112233445566778899
a0z9B1Y8c2x7
)をソルト+ハッシュすると、次のような結果になります。xyzXYZabcABC
(xyzXYZabcABC, D3W6e4v5F5)
a0z9B1Y8c2x7D3W6e4v5F5