私はマルチプレイヤーゲームを書いています。すべてを処理する中央サーバーがあります。データ交換にはHTTPSプロトコルを使用します。これはゲームなので、データ転送にRSAのような計算コストの高いシステムを使用することはできません。
ログインします、
seed
から16進数のハッシュを生成します。seed
を含む「ログイン」リクエストをサーバーに送信します。access_key
とログインが成功したことを示す応答を送信しますログインが必要なリクエストを送信するには、
access_key
およびseed
から生成されたハッシュをリクエストデータとともに送信します。access_key
とseed
から作成されたハッシュが正しいかどうかを確認します。そうである場合、新しいaccess_key
は古いデータから生成され、要求データが処理され、サーバーは要求からの応答とともに新しいaccess_key
を返します。いつでも、クライアントのIPが変更されたり、無効なaccess_key
が送信されたりすると、セッションは自動的に終了します。
このアプローチはどの程度安全ですか?それを改善するために私は何ができますか?
まず、暗号化は難しく、 自分で作成するべきではありません 。
ログインにpassハッシュの脆弱性が発生しているようです。攻撃者はログインするためにハッシュをクラックする必要はありません。ハッシュを渡すだけでログインできます。これは、最初にパスワードをハッシュする目的を無効にします。
速すぎるので、sha512はパスワードの保存にはお勧めしません。代わりに bcryptのようなもの を使用してください。
RSAは高すぎるとあなたは言う。しかし、一般に、RSAはキーの交換にのみ使用され、その後、はるかに安価な秘密キー暗号システムで使用されます。
HTTPSを使用することを明確にしたので、RSAをすでに使用していることに注意してください。 HTTPSは、鍵交換にRSAまたはdiffie hellmanを使用し、実際のデータ暗号化にいくつかのブロックまたはストリーム暗号を使用します。
HTTPSを使用すると、データの機密性と整合性(およびサーバー認証とオプションでクライアント認証)がすでに得られているため、アプリケーションレベルで追加の暗号化を行う必要はありません。
あなたの計画は実際には何の目的も果たしていないようです。あなたはすでにHTTPSを介した盗聴やデータ改ざんから保護されています(そして、あなたのスキームはとにかくそれを防いでいなかったでしょう)。
ですから、あなたのスキームは、それが認証に関するものであるため、それほどデータ交換に関するものではないようです。
通常、認証は次のように処理されます。
ログインする:
その他のリクエスト:
あなたのアプローチは似ていますが、ハッシュハッシュの脆弱性が導入されており、シードが含まれています。これは不要と思われるため、スキームを複雑にするだけです。また、各リクエストでセッションIDを再生成します。これは実際には必要ではなく、不要なオーバーヘッドを引き起こすだけのようです。
...クライアントはユーザー名、ハッシュ、シードを含む「ログイン」リクエストをサーバーに送信します。
シードはクライアントによって作成されるため、シードとハッシュの組み合わせにより、パスワードの同等物が効果的に形成され、何度でも再生できます。あなたはおそらく Digest Authentication に似たものをここに実装しようとしています。ただし、ダイジェスト認証では、ナンス(つまり「シード」)はクライアントではなくサーバーによって決定されるため、リプレイ攻撃に対して安全です。
それとは別に:スニッフィングや変更からトラフィックを保護するHTTPSをすでに使用しています。その上に別のセキュリティメカニズムを構築する理由ダイジェスト認証は通常、暗号化されていない接続に使用され、サーバーでパスワードを平文(または同等のもの)にする必要があるという問題があります。接続がスニッフィングからすでに保護されている場合は、パスワードをさらに保護する必要はなく、パスワードを平文で送信できます。これには、サーバーに元に戻せないハッシュとしてパスワードを保存できるという利点があります。