在您的情况下,您不能。即使添加身份验证签名也无济于事,因为我可能会伪装成尚未登录的用户(例如,如果用户 ID 是可预测的)。再说一次,我需要考虑重放攻击之类的事情,所以我还需要在身份验证过程中包含一个时间戳。
为了能够信任系统,我需要一个额外的服务,将发件人 ID 与其公钥进行映射。然后,每当我收到来自用户 X 的消息并且我没有他的公钥时,我可以通过发送 id=X 并获取具有到期日期的公钥来询问受信任的服务器(之后我可以缓存它),然后使用它验证消息体和时间戳,并验证时间戳是否大于上次从 X 接收到的时间戳:
1234567: X: hash=0xdeadbeef: "Debit me USD 50,74"
1234511: Y: hash=0xdeafd00d: "OK, thanks"
1234567: X: hash=0xdeadbeef: "Debit me USD 50,74"
1234515: Y: hash=0xbaadf00d: "Wait, what?"
(这里 X 和 Y 的时钟故意不同步 - 重要的是它们都是单调递增的)。
因此您需要修改服务器行为或添加辅助的、受信任的身份验证服务器,以及修改客户端协议(时间戳、哈希)和行为(密钥验证、签名... )。两台服务器之间的连接并非微不足道:密钥服务器必须访问来自主服务器的身份验证数据,并且信任连接到它的人。
在我看来,最简单的方法是聊天服务器根据用户身份验证覆盖发件人 ID。这应该是微不足道的,实际上我希望事情从一开始就以这种方式工作。
请注意,在聊天服务器上进行必要的工作以使身份验证服务器能够提供可靠的信息是不可忽略的 - 即,辅助服务器根本不是“对聊天服务器的零干预”。实际上,它比仅在聊天服务器部分的消息中注入经过身份验证的用户 ID 更复杂。主要区别在于现在您只与身份验证模块进行交互,并且在某些情况下这可能更容易做到:
您如何验证它确实是由用户 #1 发送的,而不必涉及我的服务器每次有人发送消息。
当用户第一次在主聊天服务器上创建帐户时(因此在该用户的生命周期中只有一次),聊天服务器通过可信连接与密钥服务器连接并请求密钥对对于用户 12345。密钥服务器创建该对并将私钥发送到聊天服务器,聊天服务器将其提供给用户。聊天服务器不需要做任何进一步的事情。客户端现在可以为每条消息添加时间戳和签名哈希。谁想要验证消息只需要与密钥服务器交互,并且每个发送者只需一次。