2011-02-10 83 views
0

我不是一个安全专家,所以我正在寻找人们在我设计的身份验证方案中捅漏洞,或者指出我更好,现有方案,该方案满足同一目标:寻求输入:保持服务器会话没有任何服务器状态

问题

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

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

但是,服务器不必在每次调用时都必须验证调用者,例如通过在每次调用中传递凭据。 (验证过程可能很昂贵。)

也不希望在服务器上维护会话状态。首先,它只是要求一个脆弱的解决方案,在客户端和服务器上都有独立的会话超时(客户端上的一个无法摆脱),并且为了获得可靠的会话生存期,服务器超时似乎是必要的在服务器上(而不是依靠客户端在适当的时间明确结束会话)。另一方面,服务器没有设置为存储这种状态。

服务器有明确的authenticate方法。问题是:服务器如何验证当调用另一个方法时,调用方先前已使用authenticate方法进行身份验证,而不在服务器上存储任何会话状态?

建议的解决方案

这里有一个方案,我想出来的:

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

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

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

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

所以

我担心,该方案是对多种方式天真。你看到什么弱点或不合逻辑?

回答

0

如果有人关心(这似乎不太可能,因为这个问题已经得到了很多关注!),我们最终实现了一个如上所述的方案。

一些细节有所不同,但:

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