使用基于hmac的客户端数据验证而不是会话?

时间:2012-01-24 20:38:36

标签: php session

会话的原则是在服务器端保存数据,只能由具有相应会话ID的用户访问。

有两种数据:私人或公共与客户的关系。当然,会话是公开访问的。

我们通常存储用户ID和一些随机数据(我没有任何具体的例子)。

我正在考虑根本不使用会话。而是使用检查用户发送的数据的有效性的函数。服务器将具有用于散列用户数据的私钥。

例如,如果用户的id = 9999,我们通常会将其存储在与会话ID关联的文件中。每次客户端发出请求时,我们都会检查其会话ID并从与之关联的会话文件中检索数据。

我正在考虑在客户端存储会话数据,每次客户端发出请求时,它都会发送此数据和数据的哈希值。

如果用户登录,则发送其凭据,服务器返回其id,时间戳和基于用户ID和私钥计算的哈希值。 对于将来的任何请求,服务器使用相同的函数,如果生成的散列相同,则会话有效并且数据先前已经过验证。

这是替换会话的有效方法吗? 除了不保存服务器私有会话数据之外还有什么缺点?

我对速度感到担心,我做了一个小测试...

<?php

$session = array(
    'userId' => 999,
    'timestamp' => time()
);
$privateKey = 'da39a3ee5e6b4b0d3255bfef95601890afd80709';

$startTime = microtime(true);

for ($i = 0; $i < 1000000; $i++){
    $hash = hash_hmac('sha1', json_encode($session), $privateKey);
}

echo 'Script took ' . (microtime(true) - $startTime) . ' seconds';

...打印

Script took 5.246542930603 seconds

我在笔记本电脑(Intel Duo)上运行了这个。 在我看来,这是一个负担得起的时间(每哈希0.000005247)。 测试是否正确?

编辑:时间戳与用户ID一起进行哈希处理,以确保会话到期。所以在服务器端,即使会话有效,但它太旧,也可以认为是过期的。

那么,如果我们使用私钥对数据和时间戳进行哈希处理是否可以在生产中使用?

2 个答案:

答案 0 :(得分:5)

我可以想到一些缺点......

  1. 所有Cookie数据都会在每个HTTP请求上传输,从而使请求变慢。
  2. 用户可以看到所有数据。
  3. 你还是要检查哈希的有效性,所以我不知道多少时间 这可以节省你的空间。
  4. 如果可以对哈希进行反向工程(也就是说,您没有使用某种私钥加密),则用户可以发送任何内容,并且您会说它是有效的。
  5. 如果您的哈希值无法进行逆向工程,则生成的速度可能会有些慢。您确实说您使用的是私钥,因此这很可能适用。解决方案可能无法很好地扩展。
  6. 在你想知道你做了什么之后,谁都需要维护这段代码。

答案 1 :(得分:0)

唯一的好处是你不必记住sessiond_id。这工作太多了。我不知道它被称为ViewState,但最后我使用压缩将所有这些数据存储在客户端的隐藏字段中。使用压缩而不是加密可能是一种很好的做法?这是默默无闻的安全。