在 PHP 会话中编辑加密数据

发布于 2025-01-06 02:57:47 字数 345 浏览 0 评论 0原文

我正在 PHP 中构建一个密码管理器,用户可以使用主密码存储和访问一组密码。数据库是一个简单的 XML 文件,使用 mcrypt 加密并存储在磁盘上。

编辑:每个用户都有自己的数据库文件。

问题是:当用户编辑其密码之一时,数据库必须再次解密、更改和加密。每次用户编辑某些内容时,我都必须知道他的主密码才能访问数据库,因此我必须将密码临时存储在服务器上的某个位置,或者用户在每次更改时都输入它。

我知道将密码存储在会话变量中可能会导致安全问题,那么还有另一种更安全的方法吗?

注意:我没有托管该项目的服务器的 root 或物理访问权限,因此无法更改任何配置。

I'm building a password manager in PHP where the user can store and access a set of passwords using a master password. The database is a simple XML file, encrypted using mcrypt and stored on the disk.

Edit: Each user has its own database file.

The problem is: When the user edits one of his passwords, the database must be decrypted, changed, and encrypted again. Every time the user edits something, I have to know his master password to access the database, so I have to temporarily store the password somewhere on the server or the user has type it in for every change.

I know that storing the password in a session variable can cause security problems, so is there another, more secure way to do it?

Note: I don't have root or physical access to the server hosting the project, so I can't change any configuration.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

橘香 2025-01-13 02:57:47

一个完全不同的选择是永远不将明文存储在服务器上(无论是在磁盘上还是在内存中)。您向客户端提供的 JavaScript 可用于根据他们输入的主密码在客户端浏览器中完全加密/解密数据(因此主密码也永远不会被传输 - 请记住,两个人之间的秘密只有在以下情况下才是秘密)一个死了!

在服务器上,您只能存储数据的加密版本。数据在发布到站点时已被加密。当站点将数据发送到浏览器时,数据仍然是加密的。

这解决了很多的安全问题。 主动恶意 Web 服务器仍可能危害安全性,但前提是用户主动使用 JavaScript 加载初始页面。被动攻击者(即使他们始终可以看到服务器的完整系统内存)将无法采取任何措施来损害安全性。

为了让用户登录网站(然后能够访问数据密文),您可以使用主密码之外的单独密码,使用 JavaScript 哈希(带盐! )主密码,然后将其传输到服务器(您仍应再次存储散列和加盐的密码)。

A totally different option is to never have the plaintext stored on the server (neither on disk or in memory). The JavaScript you serve to the client could be used to encrypt/decrypt the data entirely in the client's browser, based on the master password they enter (so the master password would also never be transmitted- remember a secret between two people is only secret if one is dead! ;).

On the server, you would only store the encrypted versions of the data. The data would have been encrypted by the time they get POSTed to the site. The data is still encrypted when the site servers it to the browser.

This solves a lot of the security issues. An actively malicious web server could still compromise security, but only when the user is actively loading the initial page with the JavaScript. A passive attacker (even if they could see the server's full system memory at all times) would not be able to do anything to compromise security.

For the user to login to the site (to then be able to access the data cypher text), you could either use a separate password from the master password, or have the JavaScript hash (with a salt!) the master password before transmitting it to the server (which you should still store hashed and salted again).

撩起发的微风 2025-01-13 02:57:47

一旦您将主密码存储在磁盘上,任何加密都完全没有用,而且只会降低性能。

如果有人在会话生命周期内拔出硬盘,他可以轻松使用该密码打开文件。

如果您的管理员很粗暴,那么您就……您就完成了,因为他可以在打开文件之前存储密码。所以我假设管理员就在你这边,并且你的系统配置良好。

您可以做的第一件事是磁盘加密。这实际上会大大提高安全性。如果有人在会话中使用明文密码窃取了您的硬盘,他无论如何都无法读取它。

比使用 HTTPS...这在使用密码时应该是强制性的,如果您只使用 HTTP,那么您的整个计划都是无用的。

在 php 中...我不确定你是否可以做任何事情。但是,当您使用 https 时,您可以执行以下操作:

  • 将密码存储在 $pass
  • 生成临时随机加密密钥 ($rand)
  • 存储由 $rand< 加密的密码/code> (我只使用了 XOR)
  • $rand 存储到 $_COOKIE 变量中,
  • 使用 $_COOKIE 值在每个请求上解密主密码

示例:

$pass = 'iddqd';
$rand = 'abcde';
echo base64_encode( $pass^$rand); // CAYHFQE=
$_COOKIE['phrase'] = $rand;
$_SESSION['password'] = base64_encode( $pass^$rand);
unset( $pass);

// And on every other request:
$pass = $_COOKIE['phrase'] ^ base64_decode($_SESSION['password'])

有什么附加值?以纯文本形式存储密码仅依赖于经过身份验证的磁盘访问。

生成临时短语并将其存储在用户浏览器中(并且仅在用户端)使其依赖于经过身份验证的磁盘访问+用户身份验证时生成的 cookie 值(这应该很难欺骗)。

还有一件事,当您使用 https 时,您不必担心在每个请求中发送短语(您可以每 10-100-1000 个请求更改它)。

Once you have master password stored on disk, any encryption is totally useless and it just decreases performance.

If someone just pulled out HDD during session lifetime he could easily use that password to open file.

If you get rough admin, you're just ... you're just done, because he can just store password before file opening. So I assume admin is on your side and you have system well configured.

Fist thing you can do is disk encryption. This would actually increase security a lot. If anyone stole your HDD with plaintext password in session he wouldn't be able to read it anyway.

Than using HTTPS... This should be mandatory when working with passwords and whole your initiative is useless if you're using just HTTP.

In php... I'm not sure whether you can do anything. But when you're using https you can do this:

  • store password in $pass
  • generate temporary random encryption key ($rand)
  • store password encrypted by $rand (I used just XOR)
  • store $rand into $_COOKIE variable
  • use $_COOKIE value to decrypt master password on every request

Example:

$pass = 'iddqd';
$rand = 'abcde';
echo base64_encode( $pass^$rand); // CAYHFQE=
$_COOKIE['phrase'] = $rand;
$_SESSION['password'] = base64_encode( $pass^$rand);
unset( $pass);

// And on every other request:
$pass = $_COOKIE['phrase'] ^ base64_decode($_SESSION['password'])

What's the added value? Storing password in plain text relies just on authenticated disk access.

Generating temporary phrase and storing it in user browser (and only on user side) makes it rely on authenticated disk access + cookie value generated on user authentication (which should be hard to spoof).

And one more thing, you shouldn't have to worry about sending phrase in each request (you may change it every 10-100-1000 requests) when you're using https.

带刺的爱情 2025-01-13 02:57:47

您可能需要考虑不使用密码作为直接加密密钥。尝试执行以下操作:

$_SESSION['myKey'] = md5($_POST['userName'] .$_POST['password']); //create a hash based on multiple predictable criteria

...然后使用 $_SESSION['myKey'] 而不是密码。这样你就可以将他们的密钥保持在会话状态而不暴露。

You may want to consider not using the password as your direct encryption key. Try doing something like this:

$_SESSION['myKey'] = md5($_POST['userName'] .$_POST['password']); //create a hash based on multiple predictable criteria

...and then use $_SESSION['myKey'] instead of the password. That way when you can keep their key in session state without it being exposed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文