如何将私人加密用户数据存储在数据库中,但使其可供其他选定用户使用?
Posted
技术标签:
【中文标题】如何将私人加密用户数据存储在数据库中,但使其可供其他选定用户使用?【英文标题】:How to store private encrypted user data in the database, but make them available to other chosen users? 【发布时间】:2011-11-23 16:21:16 【问题描述】:首先,如果我的问题听起来有点令人困惑,我深表歉意,我会尽力尽可能详细地描述我的场景:
我有一个网站,用户可以在其中输入有关他们自己的个人数据。它们主要是健康数据,因此是非常私密和敏感的信息。所以我需要在服务器上加密这些数据,即使服务器受到威胁,这些数据也是安全的,因为它们将使用每个用户的密码进行加密。当然,用户密码不会以明文形式存储在服务器上,只会存储密码哈希。
但我的问题是,当用户可以选择与其他用户分享他/她的一些信息时,该网站将提供“社交功能”。但这会是个问题,因为我没有任何方法可以解密用户的私人数据,所以我不能把它展示给其他用户。
您能否给我一些选择,或者至少是一些想法,如何解决这个问题?最好使用 LAMP 环境。
【问题讨论】:
【参考方案1】:这可以使用public-key cryptography解决:
-
为每个用户生成一个公钥/私钥对;并且只能使用用户密码临时解密私钥。
对于每个数据项,随机选择一个(对称)密钥S并用它加密数据d。商店 S(d)。
使用您要授予访问权限的用户的公钥 P+u 加密 S。最初,这就是您要存储其数据的用户u。
永久存储 P+u(S)。忘记所有其他键。
现在,当用户 u 想要与用户 x 共享数据时,请执行以下操作:
-
用用户的密码解密用户的私钥P-u。
使用该私钥解密存储的数据:P-u(P+u(S )) = S。
用您要与之共享信息的用户的公钥加密 S。
永久存储生成的 P+x(S)。忘记所有其他键。
现在,当任何用户x想要访问数据时,执行以下过程:
-
用用户的密码解密用户的私钥P-x。
求 P+x(S)。 (如果不存储,则意味着没有人与可怜的用户 x 共享数据)。
使用私钥,解密存储的数据:P-x(P+x(S )) = S。
使用S,解密存储的加密S(d):S(S(d)) = d.
【讨论】:
感谢您的出色解决方案。我必须阅读它 5 次才能完全消化它,但这正是我想要的,谢谢。 @Frodik 抱歉,我知道这很复杂,可以通过省略所有变量使其看起来更简单,但这会使其非常不精确。顺便说一下,看看openssl
模块实际上实现这个解决方案。
@Frodik linked openssl 模块包含一个函数列表,每个函数的签名都记录在案。对不起,但由于我倾向于放弃教程,所以我不知道。但是,***does。
我跟进问题。如果用户忘记/丢失密码,他/她的所有数据都将永远消失,并且无法恢复它们,对吗?我只是在考虑实施某种“丢失密码?”功能,用户将在其中将新密码发送到其注册的电子邮件地址。但是,我完全看不出有什么办法可以做到这一点......
但根据您的说法,解密数据需要纯文本密码,这意味着用户在每次页面加载时重新输入密码,或者密码存储在客户端机器或服务器机器上的某个变量专用(流程#1)。现在您说您可以将密码作为普通密钥存储在另一台机器中,那么您需要提供一些短的凭据或 API 以便从主服务器访问该服务器,现在如果主服务器受到损害,而不是借助专用服务器可以也受到了损害。以上是关于如何将私人加密用户数据存储在数据库中,但使其可供其他选定用户使用?的主要内容,如果未能解决你的问题,请参考以下文章
如何将对象作为数据类型传递给选择元素并使其可读以在其他地方使用它?
jquery-select2 - 将 select2 添加到现有的下拉代码中以使其可搜索