我正在编写一个 PHP 应用程序。我想将用户登录信息存储在 cookie 中,这样用户就不必在每次访问时都登录。
我想对它们进行编码或混淆,以便它们无法被读取或篡改。
执行此操作的最佳方法是什么?
更新:
我不会在 cookie 中存储密码,只是一个用户 ID,以便我知道他们是谁,但我希望对其进行编码或加密,这样就没有人可以欺骗其他用户
最佳答案
简短的回答
不要这样做。从长远来看,你会后悔的。当然,你可以加密它,但是当有人找出你的加密 key 时会发生什么。现在您只需将每个人的凭据放在盘子上交给他们(嗯,不是真的,但足够接近)。
更好的方法
为什么不创建一个随机 token 并将其与用户名一起存储,而不是加密存储用户名和密码?你想要一些相当大的东西,所以像 sha256
散列这样的东西就足够了。
$randomToken = hash('sha256',uniq_id(mt_rand(), true).uniq_id(mt_rand(), true));
然后,将其与用户一起存储在数据库中,并将 cookie 发送给客户端(我还建议对 token 进行签名以防止篡改:
$randomToken .= ':'.hash_hmac('md5', $randomToken, $serverKey);
现在,当您验证时,首先检查哈希是否匹配:
list($token, $hmac) = explode(':', $_COOKIE['remember_me'], 2);
if ($hmac != hash_hmac('md5', $token, $serverKey)) {
die('tampered token!');
}
从那里,只需通过 token 查找用户。如果找到,请将该用户登录。
我还建议在每次更改密码时更改 token 。
直接回答您的问题
注意:请勿在实时生产代码中执行此操作。你永远不能完全信任离开你的网络服务器的数据。所以不要这样暴露你的用户信息。这不值得。但是,我确实添加了一些额外的检查(例如签署 cookie)以使其更安全一些,但您已被警告...
要对其进行编码,我会使用 mcrypt
将数据加密到 cookie 中。然后,我会制作一个随机盐并将其存储在用户行中,然后使用 hash_hmac
对加密数据进行签名使用那独特的盐。这样,如果有人截获了 cookie并且找出了 crypt 的 key ,你仍然可以检测到无效的 hmac,从而找到篡改者。
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');
}
}
注意 - 这是伪代码。你需要更多的东西来保证安全(例如检查无效值,确保它成功解密等)..
不要使用长时间运行的 session !
您应该尽可能缩短 session 过期时间(我通常使用 30 分钟 session ,但有些网站会更短)。过期时间是在最后一次使用之后,因此只要该站点正在被积极使用,就没有关系。
至于为什么不使用长时间运行的 session ,这里有一些缺点:
-
磁盘空间 - 每个 session 使用相当少量的磁盘空间。但是当你有一个长时间运行的 session 时,每个新 session 只会增加之前的总数。因此,对于长时间运行的 session ,有人只需要使用新的 session ID 一遍又一遍地访问您的网站,突然间您的磁盘空间不足(假设磁盘空间正常)。
文件夹空间 - 每个 session 将一个文件放在一个文件夹中。大多数流行的文件系统会因为单个文件夹中的大量文件而变慢。所以如果你放 100 万个 session 文件,读取或写入一个 session 文件会很慢(非常慢)。垃圾收集(清理旧文件)会非常非常非常慢(如果它甚至可以运行的话)。
Session Hijacking漏洞被打开。这是因为您在网站上打开的 session 越多,猜测有效标识符就越容易(感谢 the birthday attack)。您放置的 session 越少,就越难猜出一个有效的 session 。
可能还有其他人,但这是一个快速概述。如上所述,使用签名的记住我 token ,而不是长时间运行的 session 。你会过得更好,更安全......
关于php - 对 cookie 进行编码,使其不会被欺骗或读取等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5009685/