如何在数据库中存储私密加密的用户数据,同时使它们可供其他特定用户使用?

20

首先,如果我的问题听起来有点混乱,我很抱歉,我会尽力尽可能详细地描述我的情况:

我有一个网站,用户可以在上面输入有关自己的个人数据。这些数据主要是健康数据,因此它们是非常私密和敏感的信息。因此,即使服务器被攻击,我也需要对这些数据进行加密,以便这些数据能够得到保护,因为它们将使用每个用户的密码进行加密。当然,用户密码将不会以明文形式存储在服务器上,而只会存储密码哈希值。

但我的问题是,该网站将提供“社交功能”,当用户选择与另一个用户共享他/她的一些信息时,就会出现问题。但这会成为问题,因为我将没有任何解密用户私人数据的方法,所以我无法向另一个用户显示这些信息。

请给我一些选项或至少想法,如何解决这个问题?最好使用LAMP环境。

1个回答

44
这可以通过使用公钥加密技术来解决:
  1. 为每个用户生成一个公钥/私钥对;并且只使用用户密码暂时解密私钥。
  2. 对于每个数据项,随机选择一个(对称)密钥S并使用它加密数据d。存储S(d)。
  3. 使用要授权访问的用户的公钥P+u对S进行加密。最初,这是存储数据的用户u
  4. 永久存储P+u(S),忘记所有其他密钥。

现在,当用户u想要与用户x共享数据时,请执行以下操作:

  1. 使用用户密码解密用户的私钥P-u
  2. 使用该私钥解密存储的数据:P-u(P+u(S)) = S。
  3. 使用要共享信息的用户的公钥对S进行加密。
  4. 永久存储结果P+x(S),忘记所有其他密钥。

现在,任何用户x想要访问数据时,请执行以下过程:

  1. 使用用户密码解密用户的私钥P-x
  2. 查找P+x(S)。(如果未存储,这意味着没有人与可怜的用户x共享数据)。
  3. 使用私钥解密存储的数据:P-x(P+x(S)) = S。
  • 使用S,解密存储的加密过的S(d):S(S(d)) = d。

  • 1
    感谢你提供的高效解决方案。我不得不读了五遍才能完全理解,但这正是我正在寻找的,非常感谢。 - Frodik
    1
    @Frodik 链接 的 OpenSSL 模块包含了一系列函数,并且每个函数的签名都有文档记录。很抱歉,由于我倾向于放弃教程,所以我不知道任何教程。然而,stackoverflow 提供了 一些。 - phihag
    1
    我有一个后续问题。如果用户忘记或丢失密码,他/她的所有数据都将永远丢失,没有任何方法可以恢复它们,对吗?我正在考虑实现一种“忘记密码?”功能,用户将收到新密码发送到其注册的电子邮件地址。然而,我不太清楚如何实现这一点... - Frodik
    @Frodik很不幸地,每一个解决方案都会牺牲严格的安全要求。没有任何绕过它的方法。你无法既保护你的蛋糕又吃掉它。 - phihag
    1
    但是根据您的说法,需要明文密码来解密数据,这意味着用户需要在每个页面加载时重新输入密码,或者密码存储在客户端机器或服务器机器的某个变量中(流程#1)。现在,您说可以将密码作为明文键存储在另一台机器上,那么您需要提供某些凭据或API来访问该服务器从主服务器,现在情况是主服务器被攻击后,有了它,专用服务器也可能会受到攻击。 - Ravinder Payal
    显示剩余3条评论

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接