私は自分でPHP based REST API for my Android appを構築しようとしています。インターネット上で見つけることができるさまざまなユーザー認証のすべてに混乱しているので、セキュリティに関する考慮事項を提示したいと思います。
まず、サードパーティがAPIキーを登録できるパブリックAPIを構築したくないことを明確にしたいのですが、アプリのユーザーのみがすべての登録/ログイン/リクエストの送信などを行えるようにしたい。だから私の計画は次のとおりです:
ユーザーが登録したいとき、私のアプリはまずDiffie-Hellmanメソッドを使用してサーバーと生成されたキーを交換します。このため、私のサーバーと私のアプリは、同じ素数と同じベース(pとgと呼ばれることが多い)に関する情報を保存します。次に、アプリがシークレットを生成し、p、g、およびシークレットから公開鍵を作成します。公開鍵はサーバーに送信され、サーバーはJava UUID形式のユーザーIDとサーバーの秘密、p、およびgに基づいたサーバーの公開鍵を送り返すことで応答します。最後に、両方の当事者が共通のシークレットを生成できます。トランザクション全体はTSL/SSLを使用して実行され、表示されます here 。数値のかなり長いシークレットの代わりに、SHA-512ハッシュが保存されますデータベースとアプリで。
キーを交換した後、TSL/SSLを使用して、ユーザーのアカウント情報(ユーザーID、パスワードなど)をサーバーに送信できます。アプリのシークレットはHMACに使用され、アプリインスタンス(ユーザー)がこれを送信することを許可されていることを確認します。 SHA-512ハッシュシークレットとユーザーIDをデータベースに保存したので、これを確認できます。ユーザーがログアウトした場合、またはパスワードを変更したい場合、パスワードを送信して再ログインできるようにする必要があります。パスワードは次のようにハッシュ化されます これら 指示。ログイン後、ランダムなログイントークンがユーザーのログイン状態を表すユーザーに返されます。このログイントークンもデータベースに保存されます。
すべてのリクエストでユーザーの認証情報を送信する代わりに、ログイントークンをログイン認証情報として使用し、最初のステップで生成されたシークレットを使用してHMACを実行します。したがって、リクエストを受け取った場合、HMACを使用してメッセージ認証を行うことにより、ユーザーがリクエストを送信することを承認されているかどうかを最初に確認できます。次に、送信されたログイントークンとデータベース。このトランザクションはTSL/SSLでも実行できますが、必須ではありません。
これは有効な概念ですか、それともいくつかの重要な点がないか、誤解が含まれていますか、それとも他の種類の問題がありますか?
この提案されたセキュリティシステムは CWE-602:サーバー側のセキュリティのクライアント側の強制 に対して脆弱であり、このRESTful APIにアクセスする攻撃者の能力を制限しません。基本的に、モバイルアプリに提供された秘密は攻撃者に知られます。ジェイルブレイクした電話を持つ攻撃者は、実行中のプロセスが使用するメモリを観察できます。
攻撃者があなたのAPIに完全にアクセスできると想定している必要があります。クライアントに提供されるすべての機能は、定義により攻撃者がアクセス可能であり、セキュリティレビューを受ける必要があります。まずは、 OWASPトップ1 で見つかった問題を探すのが良いでしょう。
本当に詳細な説明ではありませんが、私が理解したことから、いくつか質問があります:)
ステップ1: Diffie-Hellman鍵交換は、中間者攻撃に対して脆弱です。安全な接続TLS/SSL内で実行されている場合でも。これを回避する唯一の方法は、PKI証明書を使用することです。
ステップ2:セキュアトークンをどのようにリサイクルする予定ですか。認証に有効な期間はどのくらいですか?あなたはそれについて考えたと思います。 RESTはステートレスであるため、ログイン/ログアウトの意味がわかりません。検証するセッションがありません。トークンは特定の時間枠で有効である必要があります。
ステップ3:接続がTLS/SSLで保護されていない場合、誰かが接続を盗聴しないようにして、安全なトークンを取得し、それを使用してRESTFul APIにアクセスしますか?