web-dev-qa-db-ja.com

OAuthトークンの生成に関するベストプラクティス?

OAuth仕様 は、ConsumerKey、ConsumerSecret、AccessToken、RequestToken、TokenSecret、またはVerifierコードの起源について何も指定していないことを理解していますが、作成するためのベストプラクティスがあるかどうか興味があります非常に安全なトークン(特にトークン/秘密の組み合わせ)。

私が見るように、トークンを作成するにはいくつかのアプローチがあります:

  1. ランダムバイトを使用し、コンシューマ/ユーザーに関連付けられたDBに保存するだけです
  2. いくつかのユーザー/消費者固有のデータをハッシュし、消費者/ユーザーに関連付けられたDBに保存する
  3. ユーザー/消費者固有のデータを暗号化する

(1)の利点は、データベースが最も安全だと思われる唯一の情報源であることです。 (2)または(3)よりも攻撃を実行するのは難しいでしょう。

実際のデータをハッシュする(2)と、おそらく既知のデータからトークンを再生成できます。とにかく保存/検索する必要があるため、(1)には実際には何の利点もありません。 (1)よりもCPUを集中的に使用します。

実際のデータの暗号化(3)により、情報を知るための復号化が可能になります。これにより、必要なストレージが少なくなり、(1)&(2)よりもルックアップが少なくなる可能性がありますが、潜在的に安全性も低くなります。

考慮すべき他のアプローチ/利点/欠点はありますか?

EDIT:別の考慮事項は、新しいトークンを期限切れにして再発行する機能が存在する必要があるため、トークンに何らかのランダム値がなければならないということです。実際のデータだけで構成されているわけではありません。

質問のフォロー

暗号化を大幅に安全にするための最小トークン長はありますか?私が理解しているように、より長いトークンシークレットはより安全な署名を作成します。この理解は正しいですか?

ハッシュの観点から、特定のエンコーディングを別のエンコーディングよりも使用する利点はありますか?たとえば、16進エンコーディングを使用するAPIがたくさんあります(例GUID文字列)。OAuth署名アルゴリズムでは、トークンは文字列として使用されます。 16進文字列の場合、利用可能な文字セットはBase64エンコーディングの場合よりもはるかに小さく(予測可能)なります。同じ長さの2つの文字列の場合、大きい文字セットの方がより良い/より広いハッシュを持つようですこれはセキュリティを改善するように思えますが、この仮定は正しいですか?

OAuth仕様は 11.10秘密のエントロピー でこの問題を引き起こします。

98
mckamey

OAuthにはトークンが関連付けられていることを除いて、トークンについては何も言われていません。したがって、あなたが言及したすべてのスキームは機能します。サイトが大きくなるにつれてトークンが進化しました。以前使用したバージョンは次のとおりです。

  1. 最初のトークンは、ユーザー名、トークンシークレット、有効期限などを含む暗号化されたBLOBです。問題は、ホストにレコードがなければトークンを取り消せないことです。

  2. そのため、すべてをデータベースに保存するように変更しました。トークンは、データベースのキーとして使用される単なる乱数です。ユーザー名のインデックスがあるため、ユーザーのすべてのトークンを簡単に一覧表示して失効させることができます。

  3. ハッキング活動はほとんどありません。乱数では、データベースにアクセスしてトークンが有効かどうかを確認する必要があります。そこで、暗号化されたBLOBに戻りました。今回は、トークンにはキーの暗号化された値と有効期限のみが含まれます。そのため、データベースにアクセスせずに無効または期限切れのトークンを検出できます。

あなたを助けるかもしれないいくつかの実装の詳細、

  1. トークンにバージョンを追加して、既存のものを壊さずにトークン形式を変更できるようにします。すべてのトークンにはバージョンとして最初のバイトがあります。
  2. Base64のURLセーフバージョンを使用してBLOBをエンコードすると、URLエンコードの問題に対処する必要がなくなります。これにより、OAuth署名によるデバッグが難しくなります。
92
ZZ Coder