我正在PHP中构建一个密码管理器,用户可以使用主密码存储和访问一组密码。该数据库是一个简单的XML文件,使用mcrypt加密并存储在磁盘上。
编辑:每个用户都有自己的数据库文件。
问题是:当用户编辑其中一个密码时,必须再次对数据库进行解密,更改和加密。每次用户编辑某些内容时,我都必须知道他的主密码才能访问数据库,因此我必须将密码临时存储在服务器上的某个位置,或者用户为每次更改都输入密码。
我知道将密码存储在会话变量中会导致安全问题,那么还有另一种更安全的方法吗?
注意:我没有对托管项目的服务器进行root或物理访问,因此我无法更改任何配置。
答案 0 :(得分:1)
一旦您将主密码存储在磁盘上,任何加密都是无用的,只会降低性能。
如果有人在会话生命周期内拔出硬盘,他可以轻松使用该密码打开文件。
如果你得到粗略的管理员,你只是...你刚刚完成,因为他可以在文件打开之前存储密码。所以我假设管理员在您身边并且您已经配置好系统。
你能做的第一件事就是disk encryption。这实际上会增加很多安全性。如果有人在会话中用明文密码偷走你的硬盘,他无论如何也无法阅读。
比使用HTTPS ...在使用密码时这应该是强制性的,如果您只使用HTTP,那么整个计划就没用了。
在php中...我不确定你是否可以做任何事情。但是当你使用https时,你可以这样做:
$pass
$rand
)$rand
加密的密码(我只使用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个请求更改一次)。
答案 1 :(得分:1)
完全不同的选择是永远不要将明文存储在服务器上(无论是在磁盘上还是在内存中)。您为客户端提供的JavaScript可以用来根据他们输入的主密码完全在客户端的浏览器中加密/解密数据(因此主密码也永远不会被传输 - 记住,两个人之间的秘密只有秘密,如果一个人死了!;)。
在服务器上,您只能存储数据的加密版本。这些数据在发布到网站时就已经加密了。当站点将其提供给浏览器时,数据仍然是加密的。
这解决了安全问题的批次。 主动恶意Web服务器仍可能危及安全性,但仅限于用户使用JavaScript主动加载初始页面时。被动攻击者(即使他们可以随时看到服务器的完整系统内存)也无法做任何危及安全的事情。
要让用户登录该站点(然后才能访问数据密文),您可以使用主密码中的单独密码,或具有JavaScript哈希值(使用一个盐!)主密码,然后将其传输到服务器(你应该仍然存储哈希和再次盐渍)。
答案 2 :(得分:0)
您可能需要考虑不使用密码作为直接加密密钥。尝试做这样的事情:
$_SESSION['myKey'] = md5($_POST['userName'] .$_POST['password']); //create a hash based on multiple predictable criteria
...然后使用$ _SESSION ['myKey']代替密码。这样,当你可以将他们的密钥保持在会话状态而不会被暴露。