web-dev-qa-db-ja.com

REST API認証と認証(ウェブ+モバイル)

私はoAuth、Amazon REST API、HTTP Basic/Digestなどについて読みましたが、すべてを「単一のピース」に入れることはできません。これはおそらく最も近い状況です モバイルアプリケーション用のAPIの作成-認証と承認

API中心のWebサイト-サービスを構築したいと思います。したがって、(最初は)センターにAPIがあり、website(PHP + MySQL)はcURLAndroidおよび-を介して接続しますiPhoneネットワークインターフェイス経由。したがって、3つのメインクライアント-3つのAPIキー。また、他の開発者もAPIインターフェースを介して開発でき、独自のAPIキーを取得できます。 APIアクションは、userLevelステータスに基づいて受け入れ/拒否されます。管理者であれば、何かを削除できるなど、他のすべてはローカル(アカウント)データのみを操作できます。

最初に、認証-oAuth + xAuthまたは私の独自の実装を使用する必要があります( http://docs.amazonwebservices.com/AmazonCloudFront/latestを参照) /DeveloperGuide/RESTAuthentication.html?r=9197 )?私が理解しているように、Amazonサービスユーザーは== APIユーザー(APIキーを持っています)です。私のサービスでは、標準ユーザーを分離する必要があります/ account(Webサイトに登録した人)と開発者アカウント(APIキーが必要)。

したがって、最初にAPIキーを認証し、次にユーザーを認証する必要があります。 Amazonのスキームを使用して開発者のAPIキーを確認する(アプリを認証する)場合、ユーザー認証にはどのスキームを使用すればよいですか?

api.example.org/authを介して([〜#〜] https [〜#〜]、HTTP Basicを介して)トークンを取得し、ユーザー名とパスワードを投稿し、その後のリクエストごとにトークンを転送する方法を読みました。 。 Androidwebsiteに同時にログインしている場合、トークンをどのように管理しますか?最初のリクエスト(ユーザー名とパスワードが送信されるとき)でのみSSLを使用し、他のすべてでHTTPのみを使用している場合、中間者攻撃についてはどうですか?この例では問題になりませんか パスワード保護RESTサービス?

69
svenkapudija

常に、キーを保護する最善の方法は、キーを送信しないことです。

ただし、通常、すべての「APIキー」には2つの部分があるスキームが使用されます。非シークレットID(例:1234)とシークレットキー(例:byte [64])です。

  • APIキーを提供する場合は、サービスのデータベースに(saltedおよびhashed)キーを保存します。
  • (パスワードで保護された)ユーザーアカウントを提供する場合、パスワード(塩漬けおよびハッシュ)をサービスのデータベースに保存します。

消費者firstがAPIにアクセスするとき、接続するために

  • 「username」パラメータを送信します(「john.doe」は秘密ではありません)
  • 「APIkeyID」パラメーターを送信します(「1234」、シークレットではありません)

そして彼を返します

  • データベースのソルト(パラメーターの1つが間違っている場合、sha1(username + "notverysecret")などの反復可能なソルトを返します。
  • サーバーのタイムスタンプ

消費者はセッション期間中にソルトを保存して、物事を迅速かつスムーズに保ち、クライアントとサーバー間の時間オフセットを計算して保持する必要があります。

消費者は、APIキーとパスワードのソルトハッシュを計算する必要があります。このように、消費者は、データベースに保存されているものとまったく同じパスワードとAPIキーのハッシュを持ちますが、セクレトはネットワーク上にありません。

これで、消費者後続がAPIにアクセスし、実際の作業を行うために、

  • 「username」パラメータを送信します(「john.doe」は秘密ではありません)
  • 「APIkeyID」パラメーターを送信します(「1234」、シークレットではありません)
  • 「RequestSalt」パラメーターを送信します(byte [64]、ランダム、シークレットではありません)
  • 「RequestTimestamp」パラメーターを送信します(クライアント時間と既知のオフセットから計算)
  • 「RequestToken」パラメーターを送信します(hash(passwordhash + request_salt + request_timestamp + apikeyhash))

サーバーは、リプレイ攻撃に対して安全にするために、過去2秒以上のタイムスタンプを受け入れないようにする必要があります。

サーバーは、クライアントと同じハッシュ(passwordhash + request_salt + request_timestamp + apikeyhash)を計算できるようになりました。

  • クライアントはAPIキーを知っている、
  • クライアントは正しいパスワードを知っている
123
Eugen Rieck