【问题标题】:Seeking input: maintaining a server session without any server state寻求输入:在没有任何服务器状态的情况下维护服务器会话
【发布时间】:2011-06-25 04:05:03
【问题描述】:

我不是安全专家,所以我正在寻找人来戳我设计的身份验证方案中的漏洞,或者为我指出实现相同目标的更好的现有方案:

问题概述

我有一个接口,客户端在其中维护会话生命周期(它是 Web 服务器上的 HTTP 会话,但这并不重要)。

无状态服务器提供了一些服务,要求调用者进行身份验证(服务器有能力执行此身份验证)。

但是,希望服务器不必在每次调用时对调用者进行身份验证,例如,通过在每次调用中传递凭据。 (身份验证过程可能很昂贵。)

最好不要在服务器上维护会话状态。一方面,它只是要求一个脆弱的解决方案在客户端和服务器上都有独立的会话超时(客户端上的超时无法摆脱),并且服务器超时似乎是必要的,以便拥有可靠的会话生命周期在服务器上(而不是依赖客户端在适当的时间显式结束会话)。另一方面,服务器没有设置为存储这种状态。

服务器有一个显式的authenticate 方法。那么问题来了:服务器如何验证,当另一个方法被调用时,调用者之前已经使用authenticate 方法进行了身份验证,而不在服务器上存储任何会话状态?

建议的解决方案

这是我想出的一个方案:

authenticate 方法接受凭据作为输入参数。认证成功后,服务器返回两件事:

  • 指示执行身份验证时间的时间戳。
  • { username, timestamp } 元组的加密版本,使用私钥加密

在进一步的方法调用中,客户端将这两个值都传回服务器。然后服务器解密加密的 { username, timestamp } 元组。如果解密的时间戳与客户端发送的未加密值匹配,则服务器知道客户端之前已经过身份验证(因为这是获取有效加密值的唯一方法)。解密后的用户名告诉服务器哪个用户已通过身份验证。

可以通过仅允许当前时间 x 小时内的时间戳来强制加密密钥的有效期。这与会话超时不同,但它限制了恶意方可以使用受损时间戳的窗口。

所以

我担心这个计划在很多方面都是幼稚的。你看到了什么弱点或糟糕的逻辑?

【问题讨论】:

    标签: authentication stateless-session


    【解决方案1】:

    如果有人关心(考虑到这个问题已经引起了如此多的关注,这似乎不太可能!),我们最终实施了一个如上所述的方案。

    不过,有些细节会有所不同:

    • 服务器根据用户名、会话开始时间戳(传回给用户)和 salt 创建会话令牌。
    • 客户端不会将此令牌传递回服务器。相反,MD5 哈希是根据与此令牌连接的整个请求内容创建的。
    • MD5 散列连同时间戳和用户名(以及请求)一起发送到服务器。然后服务器重新创建会话令牌并执行相同的散列算法。如果 MD5 哈希匹配:有效请求。

    【讨论】:

      猜你喜欢
      • 2020-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-28
      • 2013-10-24
      • 2010-11-25
      相关资源
      最近更新 更多