使用加密的 MySQL 数据库条目构建 Web 应用程序?

信息安全 加密 php 数据库
2021-08-19 13:36:38

我有一些使用 MySQL 访问构建基于 PHP 的网站的经验,存储加密的用户详细信息,但所有其他字段都是纯文本。我最近的项目需要将敏感数据存储在数据库中。

我想建立一个系统,用户可以访问他自己的条目并查看纯文本结果,但即使他能够访问其他人的条目,它们也会被加密,难以理解的字符串。

我对如何实现这一点有一个想法,但也许它不是最优的,或者已经存在工具可以以更有效的方式做到这一点。

1.) 将用户名存储为纯文本,密码使用 sha1() 或更好的散列算法加上随机盐等进行散列。

2.) 获取用户的密码(不是散列的密码,而是他输入的密码)并使用它定义一个特定于该用户名和密码的密钥,然后将其存储为会话变量。由于密钥永远不会存储在除了用户的头部之外的任何地方(以他知道他的纯文本密码的形式,然后将通过将其与他的用户名和一些盐,散列等混合,以某种方式将其转换为密钥,因为他输入它登录)这应该是一个很好的解决方案吧?

3.) 使用该密钥加密或解密该用户的所有数据。

在我看来,即使有人访问了数据库并看到了纯文本用户名和加密密码的列表,他们也无法找出特定的密钥,因为它没有存储在任何地方。因此,即使获得访问权限,他们也无法破译敏感数据库字段的内容。当然,无论如何我都在设法阻止他们访问数据库,但作为一个包罗万象的努力,这似乎是一组很好的步骤。

请专家对此发表评论,并提供一些建议吗?非常感谢。

我在programmers.SE论坛上发布了这个,他们告诉我这是一个更好的问题位置。更具体地说,为什么我不应该自己这样做。如果是这样,那么有什么替代方案?

2个回答

您在谈论的是派生密钥。您描述的技术经常用于高安全性系统,但我进一步建议您使用派生加密数据密钥。这允许数据密钥与多个派生密钥一起存储,并限制派生密钥的使用。这允许数据共享、密钥环和帐户恢复。另外,请记住,派生密钥本身仅与密码一样强,因此仍应使用加盐和慢速密钥派生功能,以确保不能一次为所有用户密码形成密码派生密钥。

派生密钥往往比真正的随机密钥弱,因此您希望用它们加密尽可能少的数量。如果您只用它加密用户的数据密钥,您可以解密用户的数据密钥,然后将其存储在会话中。然后可以使用该真正随机的密钥来加密和解密用户的数据。

进一步的增强是将密钥与记录相关联,然后使用用户密钥加密该记录密钥,以便为用户提供访问权限。如果您在此处使用非对称加密,则用户可以通过使用他们希望与之共享的用户的公钥加密记录密钥并将其添加到其他用户的密钥环来向其他用户授予记录级别访问权限。

同样,对于帐户恢复,可以使用公共恢复密钥对用户密钥进行加密。私钥可以离线保存或与管理员用户相关联(具有类似的派生密钥保护),并且仅在需要恢复帐户时由客户服务使用。

使用它确实定义一个键(...),然后将其存储为会话变量。由于密钥永远不会存储在用户的头部之外的任何地方(...)

虽然是暂时的,但密钥存储在服务器中(例如,基本会话处理程序使用 /tmp 中的文件,memcached 的内存转储即使在过期后也可能会泄露密钥)。您应该检查服务器如何保持会话以验证它不会(轻松)放弃这些密钥。

您可能希望使用随机 cookie 值重新加密会话中存储的值。或者根本不存储它。

如果您在客户端执行所有加密(使用 javascript),则会获得奖励。然后服务器永远不会看到您的数据,因此攻击者无法破坏它。

(请注意,攻击者仍然可以将合法代码替换为恶意代码,并等待用户再次访问该站点以窃取其数据。这在以前是可能的)