基本的に、3つの要件があります。
- 複数のクライアントインスタンスに同じキーを使用するのは簡単ではありませんが、
- 新しい有効なキーを生成するのは簡単ではありません。
- 正当なクライアントのキーを盗むのは簡単ではないはずです。
最初の部分は非常に簡単です。2人のプレーヤーが同時に同じキーで同じサーバーにログインしないようにしてください。また、ログインしているユーザーに関する情報をサーバーで交換したり、共有認証サーバーにアクセスしたりすることもできます。これにより、異なるサーバーの異なるプレーヤーに同じキーを同時に使用しても失敗します。また、キーの使用に関する疑わしいパターンを探して、キーが漏えいしたと判断した場合は、禁止キーのリストに追加することをお勧めします。
2番目の部分の1つの方法は、すべての有効な発行済みキーのデータベースを単純に維持することです。キーが十分に長く(たとえば、128ビット以上)、ランダムに選択されている限り(安全なRNGを使用)、有効なキーを推測しようとする人のオッズは基本的にゼロです。(ログイン試行の失敗に対して何らかの種類のレート制限を使用して、ブルートフォースによる有効なキーの検索試行を停止する場合は、はるかに短いキーでも安全です。)
または、一意の識別子を取得し、秘密マスターキーを使用して計算されたメッセージ認証コード(HMACなど)を追加することにより、キーを生成できます。繰り返しますが、MACが十分に長い限り、マスターキーを知らない人がどのIDに対しても有効なMACを推測できる可能性は無視できます。この方法の1つの利点は、キーデータベースの必要性を排除することに加えて、識別子が一意の文字列であり、キーが発行されたクライアントに関する情報をエンコードできることです。
MACの使用に関する1つの問題は、公式のゲームサーバー(または少なくとも認証サーバー)がMACを検証するためにマスターキーを知る必要があることです。つまり、サーバーがハッキングされた場合、マスターキーが漏洩する可能性があります。このリスクを軽減する1つの方法は、異なるマスターキーを使用して各IDの複数のMACを計算することです。ただし、マスターサーバーの1つのみをゲームサーバーに保存します。そうすれば、そのマスターキーが漏洩して偽のIDの生成に使用された場合、それを取り消して別のマスターキーに切り替えることができます。または、MACをデジタル署名で置き換えることができます。これは、マスターキーの公開半分のみを使用して検証できます。
3番目の部分の1つのアプローチは、受信者が本当に正規の公式サーバーであることを確認せずに、クライアントがそのキーをだれにも送信しないことを確認することです。たとえば、ログインプロセスにSSL / TLS(またはDTLS)を使用し、ゲームサーバーにカスタム証明書を発行し、クライアント信頼証明書のみを発行できます。便利なことに、TLSを使用すると、クライアントキー(およびその他の認証データ)も盗聴者から保護されます(パブリックWLANなど)。
残念ながら、この方法では、サードパーティのサーバーがクライアントキーを検証することはできません。これを回避するには、サードパーティのゲームサーバーが利用できる公式の認証サーバーを設定します。たとえば、クライアントに認証サーバーにログインさせ、ランダムなワンタイムトークンを受信させて、ログインに使用できますゲームサーバー(トークンを認証サーバーに送信して検証します)。
または、クライアントに実際のクライアント証明書などを発行できます。クライアント証明書認証をサポートする既存のプロトコル(TLSなど)を使用する(推奨)か、次のように独自のプロトコルを実装することができます。
- クライアント証明書は、任意のID文字列、公開/秘密キーペア、およびIDのデジタル署名とマスターキーを使用した公開キーで構成されます。
- ログインするために、クライアントはID、公開鍵、署名を送信します。サーバーは一意のチャレンジ文字列(できればサーバーIDとクライアントが検証するタイムスタンプを含む)で応答し、クライアントは秘密鍵で署名して(キーを知っていることを証明するため)、署名をサーバーに送信します。
- サーバーは両方の署名をチェックし、ID +公開キーが正当なクライアントキーを形成し(マスターキーで署名されているため)、クライアントキーが実際にクライアントに属していることを証明します(クライアントがプライベートでサーバーのチャレンジに署名できるためキー)。
(このプロトコルは、クライアントにサーバーIDとタイムスタンプで構成される「チャレンジ」を生成させ、署名させることでさらに簡素化できます。もちろん、サーバーはIDとタイムスタンプが有効であることを確認する必要があります。この単純なプロトコルは、それ自体では、仲介者の攻撃者がクライアントのセッションをハイジャックすることを阻止しませんが、将来のログインに必要なクライアントの秘密鍵を取得することを防ぎます。