寻求输入:在没有任何服务器状态的情况下维持服务器会话

发布于 2024-10-16 14:54:12 字数 1054 浏览 6 评论 0 原文

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

问题概述< /strong>

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

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

然而,服务器最好不必在每次调用时对调用者进行身份验证,例如通过在每次调用中传递凭据。 (身份验证过程的成本可能很高。)

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

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

建议的解决方案

这是我提出的一个方案:

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

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

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

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

所以

我担心这个计划在很多方面都很幼稚。您发现哪些弱点或不良逻辑?

I'm not a security expert, so I'm looking for people to poke gaping holes in an authentication scheme I've devised, or point me to a better, existing scheme that fulfills the same goals:

Overview of Problem

I have an interface in which the client maintains session lifecycle (it's an HTTP session on a web server, but it doesn't really matter).

The stateless server provides some services that require the caller to be authenticated (the server has the ability to perform this authentication).

However, it's desirable for the server not to have to authenticate the caller on each invocation, e.g., by passing credentials in each call. (The authentication process can be expensive.)

It's also desirable not to maintain session state on the server. For one thing, it's just asking for a brittle solution to have independent session timeouts on both client and server (the one on the client can't be gotten rid of), and a server timeout seems necessary in order to have a reliable session lifetime on the server (rather than relying on the client to explicitly end the session at an appropriate time). For another thing, the server isn't set up to store this sort of state.

The server has an explicit authenticate method. The problem is then: how does the server verify that, when another method is called, the caller has previously authenticated using the authenticate method, without storing any session state on the server?

Proposed Solution

Here's a scheme I've come up with:

The authenticate method accepts credentials as input parameters. Upon successful authentication, the server returns two things:

  • A timestamp indicating the time that authentication was performed.
  • An encrypted version of the tuple of { username, timestamp }, encrypted with a private key

On further method calls, the client passes both of these values back to the server. The server then decrypts the encrypted { username, timestamp } tuple. If the decrypted timestamp matches the unencrypted value that was also sent by the client, the server knows that the client has previously authenticated (as that's the only way to acquire a valid encrypted value). The decrypted username tells the server which user has been authenticated.

The validity period of an encrypted key can be enforced by only allowing timestamps that are within x hours of the current time. This isn't the same as a session timeout, but it limits the window within which a compromised timestamp could be used by a malicious party.

So

I fear that this scheme is naive in a dozen ways. What weaknesses or bad logic do you see?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

╰つ倒转 2024-10-23 14:54:12

如果有人关心(考虑到这个问题引起的关注,这似乎不太可能!),我们最终实施了一个与上述大致相同的计划。

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

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

In case anybody cares (which seems unlikely given the amount of attention this question has gotten!), we ended up implementing a scheme much as described above.

A few of the details vary, though:

  • The server creates a session token based upon the user name, the session-start timestamp (passed back to the user), and a salt.
  • The client does not pass this token back to the server. Instead, an MD5 hash is created from the entire request content concatenated with this token.
  • The MD5 hash is sent to the server along with the timestamp and the the user name (and the request). The server then re-creates the session token and performs the same hashing algorithm. If the MD5 hashes match: valid request.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文