如何安全地存储私有数据并公开访问?

信息安全 加密 隐私
2021-09-07 14:30:12

该任务可能无法像标题中那样宽泛地解决,但这是我的方案(这有点类似于新闻通讯订阅,因此肯定已经考虑过)

我想在存储有关用户的私人数据的 Web 服务器上实现一个数据库。用户不应该有一个花哨的登录名,而是要“通过电子邮件验证”,即,对邮箱的访问应该足以进行身份​​验证。

用户应该只能创建、更新、删除他们自己的数据。中央管理应该能够将数据从网络服务器导出到安全主机。

攻击场景是 Web 服务器及其上的所有数据(包括网页脚本和数据库)都受到损害。要求是在妥协之前存储在那里的私人数据仍然受到保护(假设没有尝试进一步的用户访问)。

到目前为止,这是我的想法:要进行身份验证,我只有 users email

  • 一个新人将他的输入email到一个表单中,这会导致代表用户的 ++hash(email)存储,并且用户会收到一封邮件,其中包含一个带有参数的URLpublicencrypt(email)(因为只有 (protected)而没有 (unprotected) plus (protected) ,所以不能使用盐之类的东西,我必须求助于,不是吗?)。random noncetimestamprandom nonceemailemailusernamepasswordhash(email)
  • 现有用户hash(email)也会发生同样的情况,只有 与之前的任何尝试相同。publicencrypt(email), random nonce, 并且timestamp会有所不同。
  • 任何人访问上面生成的带有参数的URL, emailnonce可以在检查后对相应的数据库记录进行操作:是否存在匹配hash(email)和匹配nonce且不太旧的记录timestamp如果是,则用户可以继续。请注意,在此用户的 Web 会话期间,明文email可用。
  • 导出到受保护的中央管理主机是通过按原样导出加密数据来实现的。使用与用于加密的公钥匹配的私钥进行解密(后者被认为是公开的,因为它驻留在可妥协的服务器上)。

至此,通过向isValid记录添加标志来完成添加新条目。删除记录当然很容易做到。显示非机密数据(例如,何时创建或上次修改条目)也是一项微不足道的任务。

我的问题是:如何安全地处理额外的私人数据?我可能只是以加密形式(如电子邮件)存储它,但在这种情况下,内容甚至无法显示给经过身份验证的用户。他可以更改它,但不能在以后的网络会话中解密它。这当然是次优的。我唯一的想法是使用不同的密钥对附加数据进行加密:使用可重复生成的对称密钥代替非对称密钥对的公钥,即将email附加数据存储为symmetricencrypt(data,key_generated_from(email))由于明文email在用户自己的网络会话期间以及在安全主机上的解密导出中可供用户自己使用,data因此可以重建。

我看到以下问题:

  • 鉴于电子邮件地址的格式受限(例如,某些域可能经常出现),如上所述从电子邮件生成的密钥是否足够安全?
  • 实际上,鉴于电子邮件地址格式的限制,hash(email)我在仅保护电子邮件的基本概念中使用的是否足够好?(可以这么说,电子邮件地址中是否有足够的熵?)
  • 有更好的方法吗?
2个回答

我认为您可能正在寻找基于令牌的身份验证系统。他们提交电子邮件地址,服务器生成令牌并将其发送给他们,他们单击必须以某种形式将令牌发布回您的网站的链接。令牌是随机的,仅在有限的时间内有效(比如 15 分钟 - 想想 memcache ^.^),并且可以根据用户操作进行刷新。至于加密,您可以从电子邮件哈希中派生一些东西作为密钥,而永远不要保留电子邮件地址的明文版本。并拒绝在新用户阶段重用哈希..

作为旁注,仅使用电子邮件获取访问权限听起来非常可怕。请注意,现在用户会接触的大多数应用程序首先会看到的是联系人。因此,某人很有可能已经拥有用户列表和访问权限。

一个新人将他的电子邮件输入到一个表单中,这会导致 hash(email) + publicencrypt(email) + random nonce + timestamp 被存储代表用户,并且用户会收到一封包含带有参数 random nonce 和 email 的 URL 的邮件。(因为只有(受保护的)电子邮件,而不是(不受保护的)用户名和(受保护的)密码,所以不能使用盐之类的东西,我必须求助于哈希(电子邮件),不是吗?)。

您可以添加一个额外的列,其中包含一个额外的随机数据(在订阅时生成),该数据仅用作哈希计算的盐(用户的一个随机盐)。这会给您与使用(不存在的)用户名相同的效果。盐可以以明文形式存储在电子邮件的同一行中,这完全没有问题。只需每个用户使用一种盐并使其随机化,就可以了。

鉴于电子邮件地址的格式受限(例如,某些域可能经常出现),如上所述从电子邮件生成的密钥是否足够安全?

使用 PBKDF2 来增加安全性。当用户可以提供的唯一“秘密”是他的电子邮件地址时,这将为您提供尽可能多的安全性。

实际上,考虑到电子邮件地址的限制格式,我在仅保护电子邮件的基本概念中使用的哈希(电子邮件)是否足够好?(可以这么说,电子邮件地址中是否有足够的熵?)

之前已经回答过,使用存储在数据库中的盐值。

有更好的方法吗?

可能只是不完全信任将电子邮件地址作为密码。但如果这真的是一个要求,你不能做得更好。您可以在服务器上有额外的信息用于密钥派生(从电子邮件 + 服务器信息派生密钥),但这不会提高用户离线获取所有数据的攻击场景的安全性。当然,您可以使用一些加密硬件 (HSM) 并将派生密钥用作 HSM 中密钥的 PIN。这样,攻击者不仅必须从服务器转储数据并识别与每个帐户关联的电子邮件,还必须控制服务器使用 HSM 解密数据。