Basicamente, você tem três requisitos:
- não deve ser fácil usar a mesma chave para várias instâncias do cliente,
- não deve ser fácil gerar novas chaves válidas e
- não deve ser fácil roubar a chave de um cliente legítimo.
A primeira parte deve ser bem direta: não permita que dois jogadores entrem no mesmo servidor com a mesma chave ao mesmo tempo. Você também pode fazer com que os servidores troquem informações sobre usuários conectados ou entre em contato com um servidor de autenticação compartilhado, para que mesmo usando a mesma chave para diferentes players em diferentes servidores ao mesmo tempo falhe. Você provavelmente também desejará procurar padrões suspeitos de uso de chaves e, se determinar que uma chave vazou, adicione-a a uma lista de chaves banidas.
Para a segunda parte, uma maneira é simplesmente manter um banco de dados de todas as chaves emitidas válidas. Desde que as chaves sejam longas o suficiente (digamos, 128 bits ou mais) e escolhidas aleatoriamente (usando um RNG seguro), as chances de alguém conseguir adivinhar uma chave válida são essencialmente zero. (Mesmo chaves muito mais curtas podem ser seguras se você usar algum tipo de limitação de taxa em tentativas de login com falha para interromper as tentativas de encontrar chaves válidas por força bruta.)
Como alternativa, você pode gerar chaves usando qualquer identificador exclusivo e adicionando um código de autenticação de mensagem (como HMAC ), calculado usando uma chave mestra secreta. Novamente, desde que o MAC seja longo o suficiente, as chances de alguém que não conhece a chave mestra conseguir adivinhar um MAC válido para qualquer ID são desprezíveis. Uma vantagem desse método, além de remover a necessidade de um banco de dados de chaves, é que o identificador pode ser qualquer sequência exclusiva e pode codificar informações sobre o cliente para o qual a chave foi emitida.
Um problema com o uso de MACs é que os servidores oficiais de jogos (ou pelo menos o servidor de autenticação) precisam conhecer a chave mestra para verificar o MAC, o que significa que, se os servidores forem invadidos, a chave mestra poderá vazar. Uma maneira de mitigar esse risco poderia ser computar vários MACs para cada ID, usando chaves mestras diferentes, mas armazenar apenas uma das chaves mestres nos servidores do jogo. Dessa forma, se essa chave mestra for vazada e usada para gerar IDs falsos, você poderá revogá-la e alternar para outra chave mestra. Como alternativa, você pode substituir os MACs por assinaturas digitais , que podem ser verificadas usando apenas a metade pública da chave mestra.
Na terceira parte, uma abordagem é garantir que o cliente não envie sua chave a ninguém sem verificar se o destinatário é realmente um servidor oficial legítimo. Por exemplo, você pode usar SSL / TLS (ou DTLS ) para o processo de login, emitir certificados personalizados para seus servidores de jogos e ter apenas os certificados de confiança do cliente emitidos por você. Convenientemente, o uso do TLS também protegerá as chaves do cliente (e quaisquer outros dados de autenticação) contra interceptadores, por exemplo, em WLANs públicas.
Infelizmente, essa abordagem não permitirá que servidores de terceiros verifiquem as chaves do cliente, mesmo que desejem. Você pode contornar isso configurando um servidor de autenticação oficial que os servidores de jogos de terceiros possam usar, por exemplo, fazendo com que o cliente efetue login no servidor de autenticação e receba um token único aleatório que eles podem usar para efetuar login no servidor de autenticação. servidor de jogos (que envia o token ao servidor de autenticação para verificá-lo).
Como alternativa, você pode emitir certificados de clientes reais ou algo parecido para seus clientes. Você pode usar um protocolo existente (como TLS) que suporte a autenticação de certificado de cliente (recomendado) ou implementar o seu próprio, por exemplo:
- O certificado do cliente consiste em uma sequência de IDs arbitrárias, um par de chaves públicas / privadas e uma assinatura digital do ID e da chave pública usando a chave mestra.
- Para efetuar login, o cliente envia seu ID, chave pública e assinatura. O servidor responde com uma sequência de desafio exclusiva (de preferência incluindo um ID do servidor e um registro de data e hora, que o cliente deve verificar), que o cliente assina com a chave privada (para provar que conhece a chave) e envia a assinatura ao servidor.
- O servidor verifica ambas as assinaturas, provando que a chave pública ID + forma uma chave legítima do cliente (desde que foram assinadas com a chave mestra) e que a chave do cliente realmente pertence ao cliente (pois o cliente pode assinar o desafio do servidor com o privado chave).
(Esse protocolo pode ser simplificado ainda mais, fazendo com que o cliente gere o "desafio", que consiste em um ID do servidor e um carimbo de data e hora, e assine-o. Obviamente, o servidor precisa verificar se o ID e o carimbo de data / hora são válidos. esse protocolo simples, por si só, não impedirá que um invasor intermediário possa sequestrar a sessão do cliente, embora os impeça de obter a chave privada do cliente necessária para logins futuros.)