php - 对 cookie 进行编码,使其不会被欺骗或读取等

标签 php security session cookies obfuscation

我正在编写一个 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 ,这里有一些缺点:

  • DOS (Denial Of Service创建漏洞

    • 磁盘空间 - 每个 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/

相关文章:

python - 如何在 Python 代码中隐藏用户名/密码?

ios - 没有密码回退的 Touch ID 的 SecItemCopyMatching

java - 如果应用程序有多个登录(例如 Facebook、Google 和 Web 服务登录),如何在 Android 中管理 session

php - 如何从 Laravel 执行存储过程

只有深色的 php dechex

php - 使用 URL 参数将 www 重定向到 Laravel 中的非 www

java - 此 jar 包含其签署者证书将在六个月内过期的条目

javascript - 使用 javascript 使用 if 语句隐藏 div

php - 通过 .htaccess 在 PHP 中延长 session 超时

php - PHP/MySQL-查询不采用表格中的动态选项值