大厅和游戏服务器不使用相同私钥的一个潜在显着优势是,即使一个或多个游戏服务器密钥被泄露,大厅服务器密钥(其公共部分与客户端捆绑在一起,使很难改变)仍然是安全的。
据推测,游戏服务器比专用大厅服务器呈现出更大(且变化更频繁)的攻击面,因此设计您的系统以能够从对游戏服务器的攻击中恢复是有意义的,同时将大厅服务器作为尽可能难以妥协。
您的第三种选择也有这个优势,因为只有登录服务器需要知道捆绑密钥的私有部分。实际上,根据“大厅”服务器除了身份验证之外的其他功能,将关键身份验证功能分离到专用服务器上可能是一个好主意。
此外,您的第三种选择保证客户端将无法绕过大厅/登录服务器,即使他们以某种方式设法获取了游戏服务器公钥的副本(例如,从另一个受感染的客户端)。(如果客户端以某种方式获取了另一个客户端的对称密钥,客户端仍然可以绕过登录服务器,但由于这些密钥与客户端 ID 相关联,因此您的服务器应该能够检测到它。)根据您的用例,这可能是也可能不是一个优势,但至少它不应该受到伤害。
顺便说一句,我觉得我真的应该修改这个旧答案,注意有一个比上述任何一个更安全(和实用)的选项:
您还需要一些撤销受损服务器密钥的机制。最简单的方法是在签名之前将过期时间戳附加到公共服务器密钥,并让客户端拒绝使用过期密钥。当然,这意味着您必须在服务器密钥过期之前定期更改(或至少重新签名)服务器密钥,这是您想要自动化的事情。
您还可以在您的协议中包含一个选项,例如 auth/lobby 服务器向客户端发送已撤销的服务器密钥列表,即使它们看起来有效,客户端也不应该信任这些密钥。这至少允许快速撤销游戏服务器密钥,而不必等待它们过期。这可能很有用,例如,如果某些游戏服务器由无法轻松接收自动密钥更新的第三方运行,从而使其密钥使用非常短的到期时间很不方便。
当然,另一种选择可能是给这些第三方游戏服务器运营商他们自己的“分支”签名密钥,该密钥本身由根密钥签名,以便他们可以生成和签署他们自己的服务器密钥。当然,客户端随后需要能够跟踪此类签名密钥链,一直到捆绑的根密钥。并且分支密钥需要携带一些(签名的)元数据,指示它们对哪些服务器有效,以便第三方不能例如仅生成和签名他们自己的大厅/身份验证服务器密钥。
不过,好消息是您实际上不必自己实现任何这些功能,因为它们都是TLS(和DTLS )中使用的公钥基础结构模型的一部分,例如您的网络协议浏览器用于安全连接到 Stack Exchange(以及任何其他 HTTPS 网站)。虽然 TLS 是一个非常复杂的协议(由于历史积累的特性),您真的不想自己实现,但有很多TLS 库可供您使用。如今,您的语言运行时很可能甚至捆绑了一个。(如果它可以从URL 获取数据,它会这样做,或者使用与您的操作系统捆绑的一个。)https://
当然,您仍然需要学习如何配置您的 TLS 库以满足您的需求(例如,仅信任您自己的根证书并禁用您不想要的任何旧功能)以及如何生成和签署 TLS 密钥,这本身可能是一项不平凡的任务。但这肯定比自己从头开始实施安全通信协议要容易得多。