我有一个 Web 应用程序,我的任务是添加安全登录以增强安全性,类似于 Google 添加到 Google 帐户的内容。
用例
本质上,当用户登录时,我们想要检测用户之前是否授权过这台计算机。如果计算机未获得授权,则向用户发送一个一次性密码(通过电子邮件、SMS 或电话),他们必须输入该密码,用户可以选择记住这台计算机。在 Web 应用程序中,我们将跟踪授权设备,允许用户查看他们上次从该设备登录的时间/地点,并根据他们的选择取消对任何设备的授权。
我们需要一个非常轻量级的解决方案(也就是说,不需要安装客户端软件),并且适用于 Safari、Chrome、Firefox 和 IE 7+(不幸的是)。我们将提供 x509 安全性,它提供了足够的安全性,但我们仍然需要为不能或不会使用 x509 的客户提供解决方案。
我的意图是使用 cookie 存储授权信息(或者,可能使用本地存储,降级为 flash cookie,然后是普通 cookie)。
一开始脸红
跟踪两个单独的值(本地数据或 cookie):表示安全登录令牌的哈希值和设备令牌。这两个值都由 Web 应用程序驱动(和记录),并指示给客户端。SSO 令牌取决于设备以及序列号。这有效地允许设备被取消授权(所有 SSO 令牌都变得无效)并通过使用序列号和使用随机数来减轻重放(虽然不是有效的,这就是我问这个问题的原因)。
问题
使用此解决方案,某人可以只复制 SSO 和设备令牌并在另一个请求中使用。虽然序列号将帮助我检测此类滥用并因此取消对设备的授权,但检测和响应只能在有效设备和恶意请求都尝试访问之后发生,这是造成损害的充足时间。
我觉得使用 HMAC 会更好。跟踪设备、序列,使用私钥创建随机数、时间戳和散列,然后将散列和这些值作为纯文本发送。服务器做同样的事情(除了验证设备和序列)并进行比较。这似乎更容易,也更可靠......假设我们可以安全地协商、交换和存储私钥。
问题
那么,如何安全地为授权设备协商私钥,然后安全地存储该密钥?至少,如果我满足于使用本地存储或闪存 cookie 存储私钥并只是说它“足够好”,是否更有可能?或者,我可以对我的原始草案做些什么来减轻我描述的漏洞?