假设我有一个聊天室,每个人都订阅了频道:private-chatroom
任何人都可以使用以下数据发送活动client-message
:
{
sender_user_id: 1,
text: "Hello everyone!"
}
其他用户会收到该事件并显示该消息及其收到的sender_user_id
(以面值表示)。
如何验证它是否真的由user #1
发送,而不必在每次有人发送消息时都涉及我的服务器。
P.S。我正在使用auth,它只允许登录的用户发送消息,但之后没有进一步验证以验证伪造的用户ID
答案 0 :(得分:3)
在您的方案中,您不能。即使添加身份验证签名也无济于事,因为我可以伪造某些尚未登录的用户(例如,用户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的时钟故意没有同步 - 重要的是它们都是单调增加的。)
因此,您需要修改服务器行为或添加辅助,受信任的身份验证服务器,以及修改客户端协议(时间戳,哈希)和行为(密钥验证,签名......) )。两台服务器之间的连接并不简单:密钥服务器必须从主服务器访问身份验证数据,并且 trust 连接到它的人。
在我看来,最简单的方法是聊天服务器根据用户身份验证覆盖发件人ID 。这应该是微不足道的,实际上我希望事情从一开始就能以这种方式发挥作用。
注意,聊天服务器上所需的工作使得认证服务器可以提供可靠的信息是不可忽略的 - 即,辅助服务器根本不是“对聊天服务器的零干预”。实际上,它比在聊天服务器部分的消息中注入经过身份验证的用户ID更复杂。主要区别在于,现在您只与身份验证模块进行交互,在某些情况下,可能更容易实现:
如何验证用户#1真正发送的内容,而无需每次某人发送消息时我的服务器 。
当用户首次在主聊天服务器上创建帐户时(在该用户的生命周期中只有一次),聊天服务器将与可信连接上的密钥服务器连接并请求密钥对对于用户12345,密钥服务器创建该对并将私钥发送给聊天服务器,聊天服务器将其提供给用户。聊天服务器无需进一步操作。客户端现在可以为每条消息添加时间戳和签名哈希。想要验证邮件的人只需要与密钥服务器进行交互,每个发件人只需要进行一次。