我正在考虑放弃PHP的$_SESSION
(即服务器端会话处理,添加一些语言无关的风格)并使用签名的cookie代替,因为我听到了很多关于它们的好处(Flickr使用他们,所以他们也应该对我也足够好。)
我理解该技术的基本背景:使用cookie自由地将键值对从客户端传递到服务器,并对其进行签名以确保值不被篡改。
但是实施签名部分的好方法是什么?也;由于流量可能是HTTP,是否有一种使用此方法发送敏感数据(例如用户密码)的好方法,同时防止cookie窃取和/或篡改?
答案 0 :(得分:23)
我不会将此技术用于敏感数据。它可以与常规会话结合使用 - 您可以为客户端提供具有正常会话ID的cookie,但也包括应用程序在每个页面上所需的所有键/值对。这样,您就可以避免为每个页面请求访问会话存储。
您的目标应该是保持数据量非常紧张,因为它会随着每个请求一起发送。
考虑到这一点,直到......
如果数据不敏感,您可以使用由键/值对和共享密钥组合而成的sha1哈希对值进行签名。 e.g。
$values=array(
'user_id'=>1,
'foo'=>'bar'
);
$secret='MySecretSalt';
$plain="";
foreach($values as $key=>$value)
{
$plain.=$key.'|'.$value.'|';
}
$plain.=$secret;
$hash=sha1($plain);
现在给客户端一个包含所有值和哈希值的cookie。您可以在呈现cookie时检查哈希值。如果您根据客户端显示的值计算的哈希值与预期的哈希值不匹配,则表示值已被篡改。
对于敏感数据,您需要加密值。查看提供大量加密功能的mcrypt扩展程序。
关于cookie窃取,如果您将用户凭据放入cookie并信任它,那么获得该cookie的人可以冒充该用户,直到密码被更改为止。一个好的做法是记住您对用户进行身份验证的方式,并且只有在用户明确登录时才授予某些权限。例如,对于论坛,您可以让某人发帖,但不要更改他们的帐户详细信息,如电子邮件地址。
“自动登录”cookie还有其他技术,包括为这些cookie提供一个令牌值,您只允许使用一次。关于这种技术Here's a good article。
您还可以查看在签名cookie中包含客户端IP,如果它与提供cookie的IP不匹配,则会让他们再次登录。这提供了更多保护,但对于明显IP地址不断变化的人不起作用。您可以将其设为可选功能,并为用户提供退出选项的方法。只是一个无所事事的想法,我在实践中没有看到这样做:)
有关解释会话被盗,劫持和录制的好文章,请参阅Sessions and Cookies,其中提供了一些其他技巧,例如使用User-Agent标头作为附加签名。
答案 1 :(得分:16)
我完全为此目的制作了CookieStorage。所有存储的值都通过RIPEMD160散列(并随时间盐化)使用您的私钥进行安全签名,并可选择使用RIJNDAEL256进行加密。
每个值都与时间戳一起存储,时间戳是可检索的。
Signed example。
Encrypted example
如果您愿意,可以使用您选择的哈希/加密/解密函数。
答案 2 :(得分:0)
在PHP中签名的Cookie
这个问题的其他答案有点过时了。 PHP 5.2将httponly
参数添加到setcookie
函数,有效地添加了本机签名的cookie支持。根据{{1}}函数httponly parameter documentation:
"当[设置为]为TRUE时,只能通过HTTP协议访问cookie。这意味着cookie无法通过脚本语言(例如JavaScript)访问。有人建议这种设置可以通过XSS攻击有效地帮助减少身份盗用(尽管并非所有浏览器都支持),但这种说法经常受到质疑"
将此参数设置为true还会禁用使用其他基于浏览器的工具(例如Chrome的DevTools)编辑此Cookie的功能。为了使签名的cookie更加安全,我强烈建议缩小它使用的路径或域。您可以使用setcookie
和path
参数指定这些参数。当然,如果您的网站是通过HTTPS加载的,那么使用domain
参数保护cookie绝对不会受到伤害。结果将是这样的一行:
secure
为什么要使用签名的Cookie?
事实上,有一些特定的情况,其中签名的cookie是有用的,而其他方法,如会话,则不是。例如,让我们假设有问题的网站/应用程序使用负载均衡器来提高性能。现在让我们假设负载均衡器有多个物理服务器,从中提供文件,并且粘性会话选项不可用。在这种情况下,签名cookie几乎是用PHP保存状态的唯一安全方式。