0

在实现我的站点(Rails 站点,如果它有任何区别)时,我的设计重点之一是减轻用户创建另一个用户名和密码的需要,同时仍然提供有用的每个用户功能。

我打算这样做的方式是:

  1. 用户在网站上输入信息。信息通过服务器端会话与用户相关联。
  2. 用户完成输入信息,服务器通过电子邮件向用户发送访问URL,大致形式如下:http://siteurl/<user identifier>/<signature: HMAC(secret + salt + user identifier)>
  3. 用户单击 URL,站点查找用户 ID 和 salt,并使用服务器存储的秘密计算 HMAC,并验证计算的 HMAC 和签名是否匹配。

我的问题是:这是完成我想要做的事情的一种相当安全的方式吗?是否存在使其无用的常见攻击?是否有令人信服的理由放弃我避免使用用户名/密码的愿望?是否有关于该主题的必读书籍或文章?

请注意,我不是在处理信用卡号码或任何非常私密的东西,但我仍然希望保持信息的合理安全。

4

2 回答 2

5

一个词(嗯,实际上是两个)——Referer标题。您的用户在访问您的站点后访问的下一个站点将在此标头中看到他的凭据。此外,用户在以这种方式受到威胁后将无法更改其凭据。

用户名/密码身份验证的想法是它涉及两条独立的信息——一个已知的用户 ID 和一个未知的密码,可以根据每个用户自由更改。在您的系统中(除了Referer 之外),所有密码都只有一个密码——“秘密”。我还怀疑暴力破解签名(因为我知道我的用户 ID)并恢复秘密会相当容易,从而使整个系统变得无用。

于 2012-10-09T03:45:21.950 回答
1

我考虑过类似的 iPhone 应用程序的无密码登录——Web 应用程序的最大问题是登录变得不必要的乏味。

也就是说,这是一个简单的修改:

  1. 用户输入电子邮件地址。
  2. 服务器生成一个随机身份验证(例如 128 位 /dev/urandom,base64 编码)令牌并H(authtoken)与时间戳一起保存到数据库,然后发送一封电子邮件https://example.com/login/userid?auth=authtoken
  3. 用户单击 URL,服务器检查令牌是否在数据库中且未过期,从数据库中删除令牌并设置会话 cookie。

您的服务器需要存储更多状态,但无论如何它都需要存储状态。它的工作原理与任何良好的密码重置流程大致相同,这大概使其在理论上不会降低安全性。然而,在实践中,它并没有像 account-hijack-via-password-reset 那样留下明显的审计线索,因为“密码重置”流程现在是正常的登录流程。

你也可以对 MAC 和时间戳做类似的事情(uid,timestamp,MAC_k(uid,timestamp))——基本问题是任何有权访问 MAC 密钥(例如数据库备份)的人都可以生成任意身份验证令牌,并且数据库一直都在泄露。

在散列/MAC 处理时,请注意“加密拼接”攻击。

此外,一个常见的错误是透露给定的电子邮件地址是否有帐户(登录时通常会显示“无效的电子邮件/密码”,但密码重置流程会将其泄露出去——更好的方法是始终发送电子邮件,并说“有没有与此电子邮件关联的帐户”在电子邮件中,理想情况下与成功响应的字节数相同!)。

于 2012-10-09T04:50:23.317 回答