用户会话密钥可以不由发布服务器存储,是否可以被认为是安全的?

时间:2010-02-06 12:31:04

标签: database security session client-server distributed

代替服务器向客户端发出随机生成的会话字符串作为服务访问密钥(也称为“身份验证令牌”),将它们插入数据库以维护一组用户密钥关系,以便随后对每个服务请求进行验证,服务器不执行以下操作,而是在如此分布式系统中实现可比较或更好的安全性:

  1. 取用户的主键(又名“用户标识符”)
  2. 选择一个密钥到期时间戳,以及可选的客户端IP地址,以及其他值得嵌入密钥的内容
  3. 将秘密字符串作为密钥验证签名
  4. 序列化以上所有
  5. 使用服务器已知的密钥对称地加密结果,或使用服务器选择的私钥非对称加密
  6. 然后,与客户端共享作为上述步骤结果的会话密钥,例如,用饼干。使用HTTP之类的无状态协议,其中每个请求都必须使用会话密钥证明客户端身份验证,上述过程由服务器反向完成,目的是恢复经过身份验证的用户标识符。

    在其他条件相同的情况下,攻击者需要成功攻击底层加密才能伪造会话密钥,从而危及该系统的安全性。对于“其他所有内容”,我指的是弱点,比如攻击者从客户端以某种方式获取用户的会话密钥,并打算自己使用它。

    我认为,这种方法的优点是:

    1. 无需在任何地方维护有效的用户密钥关系
    2. 每个密钥中嵌入的到期值可确保任何人都无法在某个时间点之外使用密钥。
    3. 服务器基于解密的验证可能比数据库访问成本更低。
    4. 缺点可能是:

      1. 服务器使密钥无效可能会被视为有问题:
        • 即使密钥牢固嵌入,例如IP地址,服务器可以使用后者通过比较嵌入地址与服务请求后面的地址来验证密钥,可以伪造IP地址
        • 如果服务器维护一组被撤销的密钥解决了密钥撤销问题,那么可以问一下这比首先维护一组用户密钥关系更好吗?
      2. 我认为这个问题已经结束,因为它可能没有一个可接受的答案,因此不符合SO指南,但由于它仍然保持开放并得到了有用的答案,我至少不会删除它。 / p>

4 个答案:

答案 0 :(得分:2)

系统的缺点是“登录”令牌在cookie中以明文形式发送,无论令牌是否在数据库中,这都是同样的弱点,并且通过使用HTTPS连接来防范。

话虽如此,大多数网站都不使用HTTPS。他们做出了权衡。如果您不使用HTTPS,并且想要比较发送经过身份验证的cookie与发送cookie是数据库密钥,那么前者与后者相比没有任何一周。

最好还包括请求的IP地址以及到期日期。

没有必要将令牌加密存储在cookie中 - 但它同样安全,而且更straightforward发送纯文本凭据,然后是加密安全散列的凭证和秘密。有关详细信息,请参阅 HMAC 。 HMAC基本上是:

想象一下,变量username,expires,ip_address和salt(随机数)已经存储在HttpOnly cookie中;你提取它们,以及你在cookie中的哈希值。在您的脚本中,您有一个额外的“密码”,它永远不会直接存储在cookie中:

hash = hash_hmac("sha256",username+expires+ip_address+salt,"password")

此哈希的安全性基于quality of the password。这应该是一些随机的数字,字母和标点符号串,长度至少为20个字符,存储在服务器端脚本中。

如果Cookie中的哈希是正确的,您可以 某些 表示已经过哈希处理的字段未被篡改!攻击者产生有意义的碰撞的可能性将达到一个[1] - 这无疑超出了宇宙中所有计算机的计算能力和数十亿年。如果您的密码非常随意,那么它就是安全的。

但整个系统只是对坚定的攻击者的速度冲击,并且仅适用于普通网站,而不是包括支付或用户期望的安全性在内。如果没有HTTPS,系统就不安全了,使用HTTPS时,不需要对cookie进行身份验证。

确定的攻击者可以访问您的站点以恢复密码 - 在相同的情况下,没有什么能阻止他们将登录详细信息恢复到数据库,因此与此方面的问题中概述的数据库方法没有什么不同。

确定的攻击者可以复制凭据,并代表用户发送令人讨厌的请求,例如csrf等等。

等等。

[1]我低估了赔率。

答案 1 :(得分:1)

您想用什么来加密/解密数据?

一般来说,我不会建议你做上面告诉我们的事情,因为:

  • 为什么不在集中存储中拥有所有会话?您的加密算法也可能被窃取/破解。
  • 数据库访问很可能更快,更容易管理/编码

如果您的源代码被盗或算法被破坏,攻击者可以创建新的自定义会话并使自己成为管理员 - 您可以自己对其余部分进行成像

您是否在PHP中使用标准会话库?

答案 2 :(得分:0)

我喜欢这种方法,并且我将它用于我的网站,因为它很容易扩展。

我在HTTP上看到这个协议的唯一安全问题是您的请求容易受到重播攻击/嗅探。顺便说一下,在非加密传输协议上存储在cookie中的会话ID存在同样的问题,除非您在每个请求上重新生成会话ID。

额外阅读:PHP implementation包含指向此主题的优秀论文的链接(抱歉,目前无法在stackoverflow上发布多个链接;)。

答案 3 :(得分:0)

不是一个好主意。一个very similar(从根本上说,如果我理解正确,这是一个很简单的问题)几个星期后就会被问到。我的回答是(我强调强调核心点):

  

完全在客户端存储会话到期和用户名等重要数据是太危险的IMO,加密与否。即使这个概念本身在技术上是安全的(我无法深入回答,我也不是加密专家),只需获取加密密钥,就可以在不损害服务器的情况下促成闯入。

     

持有密钥的人可以随意生成会话cookie ,模仿任何用户任何时间长度,其中经典会话概念及其会话数据的集中存储旨在防止。

     

针对此问题,有更好的可扩展解决方案。例如,为什么不设置所有相关服务器和服务可以轮询的中央会话验证实例?在网上浏览,我100%确定有现成的解决方案满足您的需求。