21

AzureでクラウドサービスとしてホストされるC#を使用してRESTWebサービスを実装しています。これはRESTサービスであるため、ステートレスであり、Cookieやセッション状態はありません。

Webサービスには、HTTPS(StartSSL.comによって提供される証明書)を介してのみアクセスできます。

ユーザーがサービスに正常にログインすると、セキュリティトークンを取得します。このトークンは、将来の通信で認証を提供します。

トークンには、クライアントのタイムスタンプ、ユーザーID、およびIPアドレスが含まれます。

すべての通信はHTTPSを介してのみ行われるため、トークンが傍受されてリプレイ攻撃で使用されることは心配していません。とにかくトークンには有効期限があります。

ただし、これは公開サービスであるため、誰かがサービスに登録し、ログインして、受け取ったトークンを変更して他のユーザーのアカウントにアクセスする可能性があるのではないかと心配しています。

トークンのコンテンツを保護し、改ざんされていないことを確認するための最善の方法を考えています。

トークンを保護するために、次のことを行う予定です。

クライアントはサービスに正常にログインし、サービスは次のことを行います。

  1. ランダムな値を生成し、SHA256で1000回ハッシュします。
  2. 秘密鍵+ハッシュされたランダム値からワンタイムセッション鍵を生成します。
  3. SHA256でセッションキーを1000回ハッシュし、それを使用してトークンを暗号化します
  4. 秘密鍵を使用して、RSAを使用して暗号化されたトークンに署名します。
  5. 暗号化されたトークン+署名+ハッシュされたランダム値を暗号化されていないJSONパッケージでクライアントに送信します。

クライアントがサービスを呼び出すと、暗号化されたトークンと署名が暗号化されていないJSONパッケージでサービスに送信されます。サービスは

  1. 秘密鍵+ハッシュされたランダム値からセッション鍵を再作成します
  2. 秘密鍵を使用して署名を確認します
  3. ハッシュされたセッションキーを使用してトークンを復号化します
  4. トークンの有効期限が切れていないことを確認してください
  5. 要求された操作を続行します...

私は暗号化について何も知らないので、いくつか質問があります。

  1. これで十分ですか、それともやり過ぎですか?
  2. 改ざんを検出するには、トークンにHMACを含める必要があることを読みました。秘密鍵で署名しているので、HMACは必要ですか?
  3. RSAの代わりにRijndaelを使用する必要がありますか?
  4. Rijndaelが優先される場合、生成されたIVは復号化に必要ですか?つまり、それを捨てることができますか、それとも暗号化されたトークンを送信する必要がありますか?例:暗号化されたトークン+ HMAC +IV+ハッシュされたランダム値。

すべての通信はHTTPSを介して行われるため、暗号化されていないJSONパッケージは、クライアントに到達するまで実際には暗号化されていません。

また、後でPHPでサービスを再実装したい場合もあるので、これはすべてPHPでも実行可能である必要があります。

ご協力いただきありがとうございます

4

1 に答える 1

26

あなたは本当にトークンを考えすぎています。正直なところ、最高のトークンセキュリティは、ランダム性、より正確には予測不可能性に依存しています。最高のトークンは完全にランダムです。ユーザーが自分のトークンを変更し、それを使用して他のユーザーのアカウントにアクセスすることが懸念されるのは当然です。これは、「セッションスティーリング」として知られる一般的な攻撃です。トークンがサーバー側でランダムに生成されて期限切れになった場合、この攻撃はほぼ不可能です。IPやタイムスタンプなどのユーザー情報を使用すると、予測可能性が向上するため、お勧めできません。私は大学で攻撃を行い、マイクロ秒単位のサーバータイムスタンプに基づくアクティブなトークンをうまく推測しました。アプリケーションの作成者は、マイクロ秒は予測できないほど速く変化すると考えていましたが、

ユーザーがプロキシサーバーの背後にいる場合、プロキシはSSL要求をプレーンテキストで表示することがあることに注意してください(セキュリティ上の理由から、多くのプロキシはディープパケットインスペクションを実行します)。このため、セッションを期限切れにすることをお勧めします。そうしないと、ユーザーはこのような攻撃に対して脆弱になり、XSSやCSRFも発生する可能性があります。

妥当なキー長があれば、RSAまたはRijndaelで十分です。また、署名している場合でも、改ざんを防ぐために、トークンとともにHMACを使用する必要があります。秘密鍵を使用して署名しているため、理論的には冗長になります。ただし、HMACは非常によくテストされており、署名メカニズムの実装に欠陥がある可能性があります。そのため、HMACを使用することをお勧めします。多くの「独自の」セキュリティ実装に、妥協につながる欠陥があることに驚かれることでしょう。

あなたはセキュリティにかなり精通しているように聞こえます。良い仕事を続けてください!この世界では、セキュリティを意識した開発者がもっと必要です。

編集:

タイムスタンプ/ユーザーIDは、サーバーのみが持つ強力な対称秘密鍵(AES、Blowfishな​​ど)で暗号化されており、トークンに改ざん防止ハッシュが含まれている限り、トークンに含めるのが安全であると見なされます。ユーザーID/タイムスタンプとともに秘密鍵で暗号化されるHMACなどのそれを使用します。ハッシュは整合性を保証し、暗号化は機密性を保証します。

暗号化にHMAC(または他のハッシュ)を含めない場合、ユーザーが暗号化されたトークンを改ざんして、有効なものに復号化する可能性があります。ユーザーIDとタイムスタンプが暗号化され、ハッシュなしでトークンとして使用されているサーバーを攻撃しました。文字列内のランダムな文字を1つ変更することで、ユーザーIDを58762から58531のようなものに変更できました。「新しい」ユーザーIDを選択することはできませんでしたが、他のユーザーのアカウントにアクセスできました(これは学界でした)。 、コースの一部として)。

これに代わる方法は、完全にランダムなトークン値を使用し、サーバー側で保存されているユーザーID /タイムスタンプ(サーバー側にとどまるため、クライアントの制御外)にマップすることです。これにはもう少しメモリと処理能力が必要ですが、より安全です。これは、ケースバイケースで行う必要がある決定です。

IVおよびその他のキーからのキーの再利用/導出に関しては、キーが短期間しか有効でない限り、これは通常は問題ありません。数学的には、誰かがそれらを壊す可能性は低いです。ただし、それは可能です。パラノイドルート(私が通常行う)に行きたい場合は、すべての新しいキーをランダムに生成します。

于 2013-03-19T02:43:53.117 に答える