web-dev-qa-db-ja.com

アクセストークンを安全に保存するためのベストプラクティス

ユーザーの別のAPIのアクセストークンを保存するためのベストプラクティスは何ですか?特に、Facebookにユーザーがログインして内部のREST= apiに対して認証を行い、友達(およびその他のもの)をフェッチできるようにするための両方を許可する友達がいるアプリケーションを開発しています。

鍵を生成し、それを使用してユーザーのFacebookアカウントの長期アクセストークンとおそらく他の機密情報を暗号化することを考えていました。暗号化スキームとして、私はAES-256-CBCを使用し、キーはクライアントに送信され、クライアントはそれを保持します(そして時々それを更新します)。しかし、ランダムなキーを生成した場合、ユーザーは1つのクライアントしか使用できません。他のクライアントはFacebookのアクセストークンやその他のデータを復号化するためにそのキーを必要とするためです。解決策は、Facebookのログイン中に何かユニークなものからキーを生成することですが、残念ながら私が見つけることができるのは、データベースでユーザーのレコードを見つける必要があるユーザーIDだけです。

これについては、stackoverflowに多くのトピックがありますが、私が求めていることに対する答えはありません。実際に必要なのは、クライアント側だけが知っているキーを使用してFacebookアクセストークンとその他のデータを暗号化することです。これらのキーの作成は、ユーザーがFacebook SDKを使用して認証する場合、または現在のキーが提供される場合にのみ可能です。

何か案は?

21

クライアントが保存するものとサーバーが保存するものの合計は、ユーザー固有の秘密データ(Facebookアクセストークンなど)を回復するのに十分でなければなりません。クライアントが保存するのは、ほとんどの場合、ユーザーのパスワードです(ユーザーが複数の異なるマシンを自由に使用できるようにする場合、クライアント側の唯一の永続的なストレージ領域はユーザーの頭脳です)。私が正しく理解していれば、your serverにデータを「そのまま」保存することを望まない:サーバーが完全に侵害された場合でも、ユーザーのシークレットは安全である必要があります(可能な限り)。

これは、パスワードベースの暗号化を指します。ユーザーのパスワードから対称キーが導出されます[〜#〜] k [〜#〜]これは、ユーザーの秘密を含むバンドルを対称的に暗号化するために使用されます。 Facebookアカウント。技術的には、次のようになります。

  • ユーザーが登録するとき、彼は自分のパスワード[〜#〜] p [〜#〜]を選択し、それをサーバーに送信します。
  • サーバーはランダムなソルト値[〜#〜] s [〜#〜]を生成し、 PBKDF2 を計算します[〜#〜] p [〜#〜 ]および[〜#〜] s [〜#〜]、256ビットの出力[〜#〜] t [〜#〜]を生成します。 [〜#〜] a [〜#〜][〜#〜] t [〜#〜]の最初の128ビット、および[ 〜#〜] k [〜#〜]残りの128ビットの半分。
  • 前半([〜#〜] a [〜#〜])はサーバーのデータベースに格納されます。これは、ユーザーの認証に使用されます。
  • 後半([〜#〜] k [〜#〜])はnot保存されます。これは、そのユーザーの対称鍵です。ユーザーのシークレットは[〜#〜] k [〜#〜]で暗号化されます。
  • ユーザーがログインすると、名前と[〜#〜] p [〜#〜]がサーバーに送信されます(HTTPS経由)。サーバーはそのユーザーのソルト[〜#〜] s [〜#〜]を取得し(データベースに保存されているとおり)、再計算します[〜#〜] t [〜#〜][〜#〜] p [〜#〜]およびPBKDF2で[〜#〜] s [〜#〜]を使用)。再計算された前半[〜#〜] t [〜#〜]が保存された[〜#〜] a [〜#〜]と一致する場合、ユーザーはが認証され、[〜#〜] t [〜#〜]の後半は[〜#〜] k [〜#〜]になります。サーバーは保存されたバンドルを復号化してFacebookアクセストークンにアクセスできます。

この設定では、サーバーはstores(ディスクまたはデータベース内)のクリアテキストFacebookアクセストークンを決して使用しませんが、ユーザーがログインしたときにアクセスできます。 Facebookのアクセストークンを必要とする限り、それを(RAMに)記憶するのはサーバー次第です。

ユーザーがパスワードを変更すると、これも[〜#〜] k [〜#〜]に変更されることに注意してください(サーバーは新しいソルトも生成する必要があります[〜#〜] s [ 〜#〜]、しかしサーバーが誤ってそうしなかったとしても、[〜#〜] k [〜#〜]はまだ変更されます);したがって、サーバーは古い[〜#〜] k [〜#〜]で保存されたバンドルを復号化し、新しい[〜#〜] k [〜# 〜]パスワードが変更されたとき。パスワード変更インターフェースは慣習的に古いパスワードを要求するため、これを統合するのは難しくありませんand新しいパスワードなので、その時点でサーバーは両方を持っています。

また、パスワードを忘れると、バンドルが失われることに注意してください。その場合の回復はありません。ユーザーが自分のパスワードを忘れた場合は、パスワードのリセットを行う必要があります。これは、新規登録に似ています。新しいFacebookアクセストークンを取得する必要があります。


上記のすべてにおいて、サーバーはまだユーザーのパスワードを認識しています。サーバーが完全に侵害されてハイジャックされた場合、攻撃者はサーバーを制御している間にログインするすべてのユーザーのユーザーパスワードとユーザーのFacebookアクセストークンを観察することができます。 thatを防ぐことははるかに困難です。おそらく、サーバーがWebインターフェースのみを提供し、クライアント側のすべての「知能」がサーバーによって送信されるJavascriptである場合、それはimpossibleであり、上記のスキームよりも優れています状況。

14
Tom Leek

Facebookドキュメント:グラフAPIリクエストの保護 は簡単なソリューションを提供します。

2
ma11hew28

私は先週 セキュリティと暗号学の第10回ISC会議 に参加していましたが、 Neural Network を使用してユーザーパストークンを保存する方法が誰かから提案されたのを見ました。彼はユーザーパストークンを学習するNNを作成し、高速NN学習方法を使用して自身を更新しました。これは新しい方法であり、セキュリティを約束しますが、学習には多くの注意が必要です。

[〜#〜]更新[〜#〜]

論文はFarsiと題されていました enter image description here その意味は User Access Control Using Neural Network and chaotic system

(スタックはペルシア語の文字をサポートしていません。代わりに画像を使用しました!!!)

2
sajjadG