1

我正在尝试找到一个安全的解决方案来解决我遇到的关于 Cookie/会话和数据库数据的问题。

我已经阅读了不同的文章,例如http://www.devshed.com/c/a/PHP/Sessions-and-Cookies/,这些文章解释了不同的 Cookie 盗窃和会话固定方法,以了解我的安全问题要去面对。

问题如下:我有存储数据条目的数据库表AES_ENTRYPT(),使用用户密码对其进行加密。这意味着,即使要读取信息,我也必须使用明文密码来解密数据。

如果我只将密码存储在变量中,这可能不会成为问题,$_SESSION但这将拒绝通过 cookie 保持登录数天的能力。

换句话说,我必须将明文密码存储在 cookie 中(至少,以使该功能保持登录状态)

现在,您可以使用加盐的 MD5() 或 SHA-256() 哈希作为标识符,而不是密码。但我不能用哈希解密数据。这意味着我必须存储密码服务器端(在数据库中?还是有其他安全方式?),将它连接到标识符 - 但是密码对于有权访问数据库的每个人来说都是可以访问的,并且可以直接解密那里的数据。

有没有一种安全的方法来连接我存储在 cookie 中的标识符,并将其连接到服务器存储的用户输入(密码/帐户名),而实际上却让可以访问数据库的人有可能读取该服务器端存储用户输入?

要求是,即使在最坏的情况下,有人转储了数据库和 cookie(但无法访问服务器 RAM),该人不应该能够访问用户密码并用它解密存储的数据。

为避免混淆,简单回顾一下:

这不是用户识别问题 - 登录过程单独发生(通过通常的方式:密码/登录数据的 md5() 哈希)。我的问题是,用户数据(如地址、姓名、电子邮件)是用用户密码加密的。所以我需要登录密码来解密它们。如果用户只是登录,这没问题,因为我在 $_POST 数据中有密码,并且可以使用它。但是登录后呢?只要 $_POST 或 $_SESSION 消失,我就无法再次解密数据。


可能的解决方案

经过一些输入后,我可能想出了一个方法——它并不完全安全,但它应该工作得很好:

(这里与登录/用户认证过程是分开的,我只指加密/密钥部分)

user registers OR changes password:

    generate a new hash out of $email and $password => $auth

    do NOT store $auth in the usertable, just keep it

    generate a new random key for the user => $key (only on registering, not on pw change)

    encrypt $key with $auth, storing it into the usertable

    encrypt all user data with $key

user logs in (or after registering / password change):

    generate $auth ($password + $email)

    set cookie with $auth as variable

user is logged in (cookie / session / after login):

    decrypt $key with $auth

    use $key for data encryption / decryption (serverside)

这里唯一的问题是,如果有人可以获得 $auth,他们可以解密 $key,然后解密数据。我正在考虑为每次登录生成一个新的 $auth,但这会引发一个问题,如果旧的 $auth 丢失,我如何解密密钥。这与令牌之间的区别在于,这增加了另一层,其中令牌不是加密密钥本身。无论如何,我认为解决方案是最接近我想要的,在公钥/私钥之外。非常感谢你。

4

4 回答 4

1

在您的用户表中有一个名为的字段,token当您第一次插入用户时,它可以是随机散列......

$token = md5(uniqid(mt_rand(), true));

然后将用户 ID 和令牌存储在 cookie 中,您可以使用它来查找用户。

于 2012-06-08T08:53:31.877 回答
1

据我了解您的要求,您不能在客户端或服务器端存储密码。因此,您根本无法存储它。让用户为每个页面加载输入密码。

您可以使用例如 memcached 或 APC 将内容存储在 RAM 中,或者通过创建您自己的可以在服务器上与之通信的软件。这不会为您提供太多增强的安全性,因为任何有权访问服务器(通过 shell)的人都可以以与您的软件完全相同的方式询问密码。在我看来,它破坏了“无文件,无数据库”要求的大部分目的,但它可能是您的解决方案。

于 2012-06-08T09:01:55.570 回答
1

关键是想办法把一条信息存储在cookie中,一条信息存储在数据库中,一起得到明文密码,但单独是没用的。

我能想到的最好办法是创建一个类似于@fire 建议的随机令牌:

$token = md5(uniqid(mt_rand(), true));`

然后使用这个令牌加密密码,并将加密后的密码与 cookie 一起存储在 cookie 中userid,这样你就知道这个加密的部分是什么了。

当客户端返回时,可以使用cookie来检索数据库的row by id,您可以从数据库中拉取token来解密cookie信息,从而得到明文密码。这样,如果有人破解了 cookie,他们就会得到一个加密的密码;如果他们进入数据库,他们将获得解锁密码的密钥,但没有加密密码。

于 2012-06-08T09:23:37.137 回答
1

保持用户登录

使用简单的令牌系统,将令牌存储在用户数据库和 cookie 用户端。如果您需要有关此的更多信息,我建议您使用谷歌(这很简单)

对于纯文本密码

您可以使用多种方法将其存储在 RAM 中,这是 memcache 的一个示例

$memcache->set($token, $password); 

然后,使用以下命令从 RAM 中检索信息:

$user_password = $memcache->get($_COOKIE['token']);

有几种使用 PHP 将数据存储在 ram 中的解决方案:MemcacheAPC(用户缓存部分)

于 2012-06-08T10:20:07.880 回答