基本上,您有三个要求:
- 在多个客户端实例中使用相同的密钥并不容易,
- 生成新的有效密钥应该不容易,并且
- 窃取合法客户的钥匙应该不容易。
第一部分应该非常简单:只是不要让两个玩家同时使用相同的密钥登录到同一服务器。您还可以让服务器交换有关已登录用户的信息,或与共享的身份验证服务器联系,这样即使在不同服务器上同时为不同播放器使用相同密钥也将失败。您可能还需要查找可疑的密钥使用方式,如果确定密钥已泄漏,请将其添加到禁用密钥列表中。
对于第二部分,一种方法是简单地维护所有有效已发行密钥的数据库。只要密钥足够长(例如128位或更多)并被随机选择(使用安全RNG),任何人设法猜出有效密钥的几率就基本上为零。(如果对失败的登录尝试使用某种速率限制,以阻止通过蛮力找到有效密钥的尝试,那么即使短得多的密钥也可以安全。)
或者,您可以通过获取任何唯一标识符并添加消息身份验证代码来生成密钥。使用秘密主密钥计算(例如HMAC)来生成密钥。同样,只要MAC足够长,任何不知道主密钥就能猜测任何ID的有效MAC的人的几率就可以忽略不计。除了不需要密钥数据库之外,此方法的一个优点是标识符可以是任何唯一的字符串,并且可以对有关为其颁发密钥的客户端的信息进行编码。
使用MAC的一个问题是,官方游戏服务器(或至少是身份验证服务器)需要知道主密钥才能验证MAC,这意味着,如果服务器被黑客攻击,则主密钥可能会泄漏。减轻这种风险的一种方法是,使用不同的主密钥为每个ID计算多个MAC,但仅将其中一个主密钥存储在游戏服务器上。这样,如果该主密钥曾经泄漏并用于生成伪造的ID,则可以将其吊销并切换到另一个主密钥。或者,您可以用数字签名替换MAC。,仅可以使用主密钥的公共一半来验证。
对于第三部分,一种方法是确保客户端在不验证接收者确实是合法的官方服务器的情况下不会将其密钥发送给任何人。例如,您可以使用SSL / TLS(或在登录过程中 DTLS),为游戏服务器颁发自定义证书,并且仅由您颁发客户端信任证书。方便地,使用TLS还可以保护客户端密钥(以及任何其他身份验证数据)免受窃听,例如在公共WLAN上。
不幸的是,即使第三方服务器愿意,这种方法也无法让第三方服务器验证客户端密钥。您可以通过设置第三方游戏服务器可以使用的官方身份验证服务器来解决此问题,例如,通过让客户端登录到身份验证服务器并获得随机的一次性令牌,他们可以使用该令牌登录到游戏服务器(然后将令牌提交给身份验证服务器以进行验证)。
或者,您可以向客户颁发实际的客户证书或类似的证书。您可以使用支持客户端证书认证(推荐)的现有协议(例如TLS),也可以实现自己的协议,例如:
- 客户端证书由任意ID字符串,公共/专用密钥对以及使用主密钥的ID和公共密钥的数字签名组成。
- 要登录,客户端发送其ID,公钥和签名。服务器用唯一的质询字符串(最好包括服务器ID和时间戳,客户端应验证该字符串)进行答复,客户端用私钥对其进行签名(以证明他们知道密钥)并将签名发送给服务器。
- 服务器检查两个签名,以证明ID +公钥构成合法的客户端密钥(因为它们是用主密钥签名的),并且该客户端密钥实际上属于客户端(因为客户端可以用私有签名服务器的质询)键)。
(可以通过使客户端生成由服务器ID和时间戳组成的“挑战”并对其进行签名来进一步简化此协议。当然,然后服务器需要验证ID和时间戳是否有效。也请注意,这个简单的协议本身不会阻止中间人攻击者劫持客户端的会话,尽管它将阻止他们获取将来登录所需的客户端私钥。)