编码cookie,所以他们不能欺骗或阅读等 [英] Encoding cookies so they cannot be spoofed or read etc

查看:170
本文介绍了编码cookie,所以他们不能欺骗或阅读等的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个PHP应用程序。我想在Cookie中存储用户登录信息,因此用户不必在每次访问时登录。

I am writing a PHP application. I want to store user login information in cookies so user's dont have to log in on every visit.

我想对它们进行编码或模糊处理,使其无法读取

I want to encode them or obfuscate them so that they cannot be read or tampered with.

这是最好的方法是什么?

What is the best way to do this?

更新:

我不会在cookie中存储密码,只是一个用户ID,所以我知道他们是谁,但我想这是编码或加密,所以没有人可以欺骗其他用户

I am not going to be storing passwords in the cookies, simply a user ID so that I know who they are, but I want this to be encoded or encrypted so no one can spoof other users

推荐答案

简短回答



你会后悔长期。当然,你可以加密它,但是当有人计算出你的加密密钥时会发生什么。

The short answer

Don't do it. You'll regret it in the long run. Sure, you could encrypt it, but what happens when someone figures out your encryption key. Now you just handed everyones credentials to them on a plate (well, not really, but close enough).

为什么不创建一个随机令牌并用用户名存储用户名和密码?你会想要一个相当大的东西,所以像 sha256 哈希应该足够了。

Instead of storing the user-name and password encrypted, why not create a random token and store that with the username? You'd want something sizable, so something like a sha256 hash should suffice.

$randomToken = hash('sha256',uniq_id(mt_rand(), true).uniq_id(mt_rand(), true));

然后,将它存储在用户的db中,并发送一个cookie到客户端我还建议您签名该令牌以防止篡改:

Then, store it in the db along side the user, and send in a cookie to the client (I'd also suggest signing the token as well to prevent tampering:

$randomToken .= ':'.hash_hmac('md5', $randomToken, $serverKey);



现在,当您验证时,首先检查哈希匹配:

Now, when you verify, first check that the hash matches:

list($token, $hmac) = explode(':', $_COOKIE['remember_me'], 2);
if ($hmac != hash_hmac('md5', $token, $serverKey)) {
    die('tampered token!');
}

从这里,只需通过令牌查找用户,如果你找到一个,记录该用户。

From there, just lookup the user by the token. If you find one, log that user in.

我也建议在每次更改密码时更改令牌。

I'd also suggest changing the token on every single password change.

注意:不要在实时生产代码中执行此操作。您永远不能完全信任离开您的网络服务器的数据,因此请勿公开您的用户信息。这不值得。但是,我添加了一些额外的检查(例如签名cookie),以使它更安全,但你已经被警告...

Note: do not do this in live, production code. You can never fully trust data that leaves your web-server. So don't expose your user's info like that. It's not worth it. However, I did add some additional checks (such as signing the cookie) to make it somewhat safer, but you have been warned...

为了编码,我会请使用 mcrypt 将数据加密到Cookie中。然后,我将随机创建一个盐,并将其与用户行一起存储,然后使用 hash_hmac 使用这种独特的盐。这样,如果有人截取Cookie ,就可以找出隐藏的密钥,您仍然可以检测到无效的hmac,因此您可以找到篡改。

To encode it, I would use mcrypt to encrypt the data into the cookie. Then, I would make a random salt and store it with the user row, and then sign the encrypted data with hash_hmac using that unique salt. That way, if someone intercepts the cookie and figures out the key to crypt, you can still detect the invalid hmac, so you can find tampers.

function generateCredentialsCookie($user_id, $password) {
    $encrypted = encrypt($user_id.':'.$password, $secretkey);
    $salt = uniq_id(mt_rand(), true);
    $encrypted .= ':'.hash_hmac('sha256', $encrypted, $salt);
    storeSaltForUser($user_id, $salt);
    set_cookie('credentials', $encrypted);
}

function readCredentialsCookie() {
    $parts = explode(':', $_COOKIE['credentials']);
    $salt = array_pop($parts);
    $encrypted = implode(':', $parts); //needed incase mcrypt added `:`
    $raw = decrypt($encrypted, $secretkey);
    list ($user_id, $password) = explode(':', $raw, 2);
    if ($salt == getSaltForUser($user_id)) 
        return array($user_id, $password);
    } else {
        return die('Invalid Cookie Found');
    }
}

-码。您将需要更多的安全性(例如检查无效值,确保解密成功等)。

Note - that's pseudo-code. You'll need much more in there to be secure (such as checking for invalid values, making sure it decrypts successfully, etc)..

您应该保持会话过期时间尽可能低(我通常使用30分钟会话,但有些网站较低)。过期时间是最后一次使用后,因此只要网站被积极使用,这就没关系。

You should keep your session expiration as low as practical (I typically use 30 minute sessions, but some sites are lower). The expire time is after the last usage, so as long as the site is being used actively it won't matter.

至于为什么不使用长时间运行的会话,这里有一些缺点:

As far as why not to use a long running session, here are some cons:


  • 磁盘空间 - 每个会话使用相当少量的磁盘空间,但是当您有一个长时间运行的会话时,每个新会话只会增加以前的总因此,对于长时间运行的会话,有些人只需要持续访问您的网站,一个新的会话ID,突然你没有磁盘空间(假设一个完整的磁盘)。

  • Disk space - Each session uses a reasonably small amount of disk space. But when you have a long running session, each new session only adds to the prior total. So with long-running sessions someone just needs to keep visiting your site over and over with a new session id and all of a sudden you're out of disk-space (assuming a sane disk).

文件夹空间 - 每个会话在一个文件夹中占用一个文件最流行的文件系统将减慢单个文件夹中的大量文件所以如果你放置了100万个会话文件,或者写入会话文件将会很慢(非常慢),而垃圾收集(清除旧文件)将非常慢(如果它甚至会运行)。

Folder space - Each session takes one file in one folder. Most popular filesystems will slow down with a large number of files in a single folder. So if you put 1 million session files, reading or writing to a session file will be slow (very slow). And garbage collection (which cleans old files) will be VERY VERY VERY slow (if it'll even run at all).

会话劫持漏洞已打开。这是因为您在网站上打开的会话越多,猜测有效标识符就越容易(感谢生日攻击)。

Session Hijacking vulnerabilities are opened up. This is because the more sessions you have open on the site, the easier it will be to guess a valid identifier (thanks to the birthday attack). The fewer sessions you have laying around, the harder it will be to guess a valid one.

有可能是其他人,但这是一个快速概述。而不是长时间运行的会话,请使用如上所述的签名的remember-me令牌。你会更好,更安全...

There are likely others, but that's a quick overview. Instead of long-running sessions, use a signed remember-me token as described above. You'll be far better off, and far more secure...

这篇关于编码cookie,所以他们不能欺骗或阅读等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆