在 Web 应用程序中加密部分用户数据与密码恢复

信息安全 加密 Web应用程序
2021-08-16 09:26:01

我正在开发一个存储敏感用户数据的网络应用程序。尽管数据很敏感,但我们希望将其永久存储,因为用户可能希望稍后返回并重新使用它。在用户会话期间,服务器必须可以访问用户数据。

我们可以假设与永久存储的数据集数量相比,活动会话的数量较低。

  • 资产:存储在数据库中的部分数据非常敏感 - 但需要在用户会话期间在服务器端进行处理(这是应用程序的重点)并永久存储在那里(出于可用性原因)。
  • 场景:黑客获得了对数据库的访问权限,并能够读取其中的所有数据。

注意:这并不意味着替代风险分析或安全管理的任何其他部分,也不意味着替代某些其他措施(密码策略、SSL/TLS、审计......你可以说它)。这是关于检查一项特定的安全措施。

建议的对策:用户数据加密

为了降低将所有敏感数据泄露给获得数据库访问权限的攻击者的风险,我想加密数据(与此问题中的选项 1 非常相似):

  1. 在用户注册期间,服务器会生成一个用户密钥U(AES)。
  2. 用户密钥使用密码派生密钥 (SHA256) 加密d(p)并存储在数据库中AES(d(p), U)
  3. 每次用户登录时,密钥都会被解密并存储在服务器端会话存储p -> d(p) + AES(d(p), U) -> U中。
  4. 只要会话持续,用户就可以使用他/她的数据。数据使用随机 AES 密钥(消息密钥m)加密。然后使用用户密钥对 AES 密钥进行加密,并与加密数据一起存储 ( AES(U, m) + AES(m, data))。

问题1:该方案是否存在明显的安全漏洞(攻击者可以访问所有登录用户的数据除外)?


找回密码

上述方案的一个明显缺陷是没有进行密码恢复的过程:一旦密码丢失,用户密钥就无法解密,因此数据也丢失了。

为了解决这个问题,我们生成另一个 RSA 密钥对 ( M_pub + M_sec)。公钥是应用程序配置的一部分。除了之前的方案:

  1. a) 用户密钥和用户电子邮件使用主密钥加密,并与用户记录一起作为恢复信息存储 RSA(M_pub, U+user.email)

我们在另一台服务器上有另一个应用程序,它可以访问私有主密钥(但不能访问数据库)。密码恢复将如下所示:

  1. 用户像往常一样开始密码恢复(重置密码-> 带有表单链接的电子邮件)。
  2. 用户选择一个新密码p'
  3. 原始应用程序现在要求密码重置应用程序通过将恢复信息RSA(M_pub, U+user.email)和新密码派生密钥d(p')发送到恢复服务器来解密用户密钥。
  4. 密码重置应用程序解密恢复信息M_sec + RSA(M_pub, U+user.email) -> U + user.email,发送通知电子邮件给user.email(告诉用户如果他/她没有导致恢复,则报告事件)并将新加密的用户密钥发送AES(d(p'), U)回原始应用程序。

恢复过程将受到速率限制,因此在发现泄露之前,泄露密钥的数量受到限制。

优点:

  • 密码恢复仍然是即时的。
  • 攻击者需要破解两个系统才能访问完整的数据库。

缺点:

  • 能够访问一个系统的攻击者也可能获得对密码重置系统的访问权限。

问题2:这种密码恢复方式在多大程度上降低了加密的效果?(还值得做吗?)

问题 3:是否有任何其他流程可以提高数据安全性(如果服务器被黑客入侵)而不使自动密码恢复成为不可能?

2个回答

问题 1

问题一:该方案是否存在明显的安全漏洞(攻击者可以访问所有登录用户的数据除外)?

提议的方案:

登记

  1. 用户使用P明文密码消化密码密钥pSHA 256
  2. 用户通过安全连接将此密钥发送到服务器
  3. 服务器生成一个随机密钥k,用于在存储数据之前对数据进行加密
  4. 服务器加密kP存储以供以后使用

验证

  1. 用户消化密码密钥P并将其发送到服务器
  2. 服务器解密k并存储在内存中

安全问题

密码派生

上述方案建议p进行散列。仅此一项并不能确保“完美”的前向安全性,因为可以在彩虹表中查找哈希值来检索用户的纯文本密码。由于缺少盐,攻击者还可以使用一个破解的哈希值来确定其他用户的密码。这些问题主要与隐私相关,因为它们仅涵盖了攻击者可以访问数据库时可能发生的情况。

总结上述漏洞:

  • 彩虹表查找
  • 蛮力
  • 相同的哈希值

如何解决问题

登记

  1. 用户生成S足够大小的随机盐
  2. P用户从纯文本密码中派生出一个密码密钥,pS使用key derivation function诸如PBKDF2
  3. S用户通过安全连接发送此密钥到服务器
  4. 服务器存储 S
  5. 服务器生成一个随机密钥k,用于在存储数据之前对数据进行加密
  6. 服务器加密kP存储以供以后使用

注意:盐对用户来说应该是唯一的,并且密钥派生函数应该运行尽可能长的时间(校准它运行大约一秒钟)。

问题2

问题2:这种密码恢复方式在多大程度上降低了加密的效果?(还值得做吗?)

提议的方案:

登记

  1. 用户的电子邮件随同发送 P
  2. P服务器使用恢复服务器的公钥加密用户的电子邮件并将其存储

恢复

忽略实际的“用户选择新密码”部分(与注册过程相同)

  1. 服务器将用户的电子邮件和密码密钥(均使用恢复服务器的公钥加密)发送到恢复服务器
  2. 恢复服务器解密请求的数据并将其发送回主服务器
  3. 主服务器能够使用新密码密钥加密数据

安全问题

使用“万能钥匙”时总是存在物理威胁。很高兴您已经了解将它放在单独的服务器上的单独系统上至关重要,这样如果一个系统受到损害 - 可以采取措施确保存储的数据保持安全。

私钥存储在这里要广泛回答,但我会尝试为您提供一些资源,以便您自己进一步研究。

两台服务器之间连接的安全性非常重要。即使有中间人,他们也必须能够相互信任。HTTPS 是不够的,多层安全性是确保用户数据不被泄露的一步。在这种情况下,使用 SSL/TLS 之上的会话密钥和 RSA,应用程序安全层可以做得很好。

然后是实用...

恢复系统的受信任管理员可以获得私钥并将其用于不同的恶意原因。

使用 RSA 加密大量数据在今天是不可行的。这将需要很长时间才能使用。今天的标准解决方案是生成一个随机加密密钥,用密钥加密有效载荷,用接收者的公钥加密密钥本身。然后将有效负载和加密密钥都发送到服务器,然后服务器使用其私钥解密加密密钥,并使用加密密钥解密有效负载。

任何有权访问用户电子邮件的人都不能恢复用户的密码。您提到了“双重身份验证服务”,这将有助于确保只有用户才能更改密码。

总结:

每次通过网络发送数据时,都会面临漏洞。它通过网络的时间越少 - 遇到 MITM 的可能性就越小。这可以使用标记化来解决,该标记化将敏感数据替换为只有您的服务器才能与数据相关的随机字符串。

到目前为止,大量数据无法使用 RSA 进行充分加密。

如何解决问题

恢复

忽略实际的“用户选择新密码”部分(与注册过程相同)

  1. 服务器生成一个随机加密密钥来加密有效载荷
  2. 密钥使用恢复服务器的公钥加密
  3. 服务器使用“有效负载密钥”加密用户的电子邮件和密码密钥(两者都使用恢复服务器的公钥加密)并将其和加密的有效负载密钥发送到恢复服务器
  4. 恢复服务器使用其私钥解密负载密钥,然后使用接收到的负载密钥解密请求的负载,然后使用其私钥解密数据
  5. 使用多层加密的相同通信步骤将数据发送回主服务器。
  6. 主服务器能够使用新密码密钥加密数据并再次存储

很抱歉给大家的游行下雨,但这真是个坏主意。(好线程顺便说一句!但对错误问题的正确答案。

您创建了一个复杂的 DIY 加密方案,这通常是一个坏主意,因为您的实施将引入比现在更多的漏洞。

退后一步,进行威胁分析。

  1. 从资产开始——数据的敏感程度。
  2. 想想漏洞——攻击媒介是什么?
  3. 然后考虑威胁 然后然后才考虑
  4. 思考安全对策

在进行威胁分析之前,您永远不应该从设计和实施安全对策开始。

现在我已经完成了讲座 - 让我们考虑一些典型的威胁场景。

威胁场景一:攻击者在猜到你的 SSH 密码后获得 root 访问权限,并通过猜测具有 sudo 权限的用户的密码来提升权限。您的方案对特权提升攻击无效。

威胁场景 2:SQL 注入 - 攻击者成功获得对您的 SQL 服务器的管理员访问权限 - 正确的对策是使用存储过程并清理您的输入,以确保您缓解 SQL 注入漏洞。

威胁场景 3:用户滥用 SOP(权限分离) - 即用户可能试图查看/URL hack 其他用户的数据。这是敏感医疗数据中的典型威胁场景。在这种情况下(我不知道您使用的是哪种 Web 应用程序框架),适当的安全对策是 RBAC - 基于角色的身份验证 - 而不是以用户为中心的加密。通常在诸如 RoR 和 CakePHP 或 Dot Net 之类的 MVC 框架中 - RBAC 已融入框架,因此您不必发明轮子。

威胁场景 #4 - 有人窃取了您的服务器。

您说您正在开发一个 Web 应用程序。我假设您使用的是云服务器。希望在亚马逊、Rackspace 或 Azure 等优秀的云提供商上。

如果有人物理地窃取磁盘或服务器,加密服务器上的数据只是一种有效的安全对策。

有人在 Amazon、RS 或 Azure 上窃取您的 VM 的可能性是......正确......零。

有时 - 静态数据加密的合规性要求 - 这几乎总是与可移动/移动设备有关,但如果您必须在现代 SQL 服务器中存在 TDE(透明数据加密功能) - 例如 MS SQL 和 PG