使用密码加密用户数据并忘记了我的密码

信息安全 加密 Web应用程序 密码
2021-08-11 20:29:19

我打算做一个存储大量个人资料(信息、照片......)的网络应用程序。为了给用户一种保护感,我想在将数据存储到数据库之前对其进行加密。

因此,在数据库中,我将存储密码的哈希值(用于验证)和用户数据(使用密码作为密钥加密 - 或从密码派生的密钥)。

如何提供忘记密码选项?我看到唯一的方法是将密钥存储在某个地方,这首先消除了加密数据的好处。

3个回答

执行此操作的标准方法如下:

  1. 使用加盐密钥派生算法(例如 PBKDF2 或 bcrypt)创建身份验证哈希。
  2. 生成用于数据加密的随机代理密钥。使用此密钥加密所有数据。
  3. 使用不同的盐从密码生成“锁定”密钥,但仍使用强 KDF。
  4. 将代理键与锁定键异或并存储该值。这使得主密钥未知,除非密码未知。
  5. 登录时,生成锁定密钥并与存储的代理密钥进行异或,从而为您提供真正的代理密钥。

该系统的好处是它允许轻松更改密码 - 只需使用旧密码解密代理密钥,然后从新密码生成新的锁定密钥。

使用这种机制时,解密数据的唯一方法是拥有密码,除非您使用另一个秘密创建代理密钥的第二个加密副本。

这是我的做法:

  1. 要求用户为您提供 3 个秘密答案。将答案转换为大写并将它们连接起来。通过 KDF 运行该值以创建辅助锁定密钥。
  2. 将代理密钥与辅助锁定密钥异或,并将其存储为备用密钥。
  3. 当用户忘记密码时,询问他们的秘密答案并生成辅助锁定密钥,然后使用它来计算代理密钥。

秘密答案选项是最简单的,但可以使用任何秘密值来执行此操作。

有两种方法可以解决“忘记密码”问题:

  1. 加密数据不是用一个密码,而是用两个密码。为了提高效率,请使用中间密钥:数据文件使用随机文件密钥K加密,密钥K加密两次:一次使用第一个密码,一次使用第二个密码。无论如何,您实际上都需要一个中间密钥,以支持密码更改,而无需重新加密所有数据。

    在这种情况下,第二个密码将是用户不会忘记的“备份密码”。这种奇迹(用户如何不会忘记他从未使用过的密码,因为他设法忘记了他经常使用的密码?)可以通过多种方式实现:备份密码可以是用户写入的一长串字符放在一张纸上,存放在保险箱(或他的钱包)中;备份密码可能包括对“安全问题”的回答(正如@Polynomial 所建议的那样);...

  2. 使用密钥托管用户密码或中间密钥K的副本可以由“受信任的第三方”存储,以便在紧急情况下解锁。TTP 必须得到充分保护,并同意仅作为官方、受控和审计仪式的一部分来解锁托管机密,在该仪式中,数据所有者(忘记密码的用户)通过某种物理方式(例如,通过进入显示的人和他的驾驶执照)。如果使用非对称加密,可以在不与 TTP 交互的情况下执行托管步骤:TTP 具有 RSA 密钥对,用户的密码用公钥加密,TTP 使用私钥解锁丢失的密码。

    密钥托管是否适用实际上取决于上下文,最终取决于您可以让用户为解锁其宝贵数据支付多少费用。在另一种情况下,Microsoft 的BitLocker驱动器加密技术(包含在最新/昂贵的 Windows 版本中)支持密钥托管,以便系统管理员可以保存忘记密码的用户的数据。

    密钥托管意味着服务器(在 TTP 的帮助下)理论上可以在未经用户同意甚至不知情的情况下解锁用户数据。好在用户数据不是他自己的,用户不可用(比如在一个企业中,当一个用户被公交车撞到时,他的继任者必须能够读取存储的业务数据,而之前的租户不能再给他的密码)。相反,大肆宣传的Mega网站故意放弃各种托管和丢失密码的恢复,以非常合法的方式确定他们无法在没有用户合作的情况下访问数据。

提出一种描述性稍差但更具概念性的方式,基本上您想提供两种不同的方式来获取相同的密钥。这是拥有一个数据密钥的想法,通常对于记录,或者可能对于所有用户的记录都是唯一的,具体取决于安全需要。然后,您使用从他们的密码派生的密钥和从其他一些信息派生的密钥对该密钥进行加密。这可能是他们知道的替代事物,也可能是您的服务器知道的事物。这可以是对称加密,也可以是为了更高的安全性,您的服务器知道的信息可以将公钥用于未保存在服务器上的私钥。

然后,如果用户丢失了密码并因此无法访问数据密钥,则可以对其进行的替代加密进行解密以检索密钥。为了安全起见,将密钥对称地存储在服务器上是最不安全的,就好像服务器和数据库都受到损害一样,加密变得无用。用户信息可能会好一点,但为了易于记忆,它也可能很容易研究或猜测,即使服务器没有受到损害,这也是不安全的。服务器无法访问重置所需信息的非对称选项(因为它只知道如何加密数据密钥的恢复版本是最安全的,

不管怎样,基本原理都是一样的。如果没有秘密,您总是使密钥无法恢复,您只需使用不同的秘密多次存储它。