从这个较早的问题中,我一般需要混淆存储在用户帐户中的一组第三方凭据,然后在内部 Winforms 软件客户端中使用这些凭据。已接受答案的方案如下:
密码创建和加密:
- 已经通过内部系统认证的用户为该系统选择新密码P和/或更改敏感数据D。
- 客户端软件使用 SHA-512 对P进行哈希处理,生成C。
- 客户端将C分成两半,得到C1和C2。
- 客户端使用C1和随机生成的 IV 作为密钥,使用 AES-256加密D ,生成S(包括 IV)。
- 客户端将U、C2和S传输到服务器。
- 服务器 BCrypts C2生成H(包括随机盐)。
- 服务器将U、H和S存储在服务器中。
正常登录:
- 用户输入登录凭据(用户名U和密码P)。
- P使用 SHA-512 进行散列以产生C / C1 / C2。
- U和C2被传送到服务器。
- 服务器用 BCrypt 对C2进行散列以产生H。
- 服务器使用用户名U检索用户记录,并根据存储的值验证H。
- 服务器传输加密的用户数据S。
- 客户端使用C1解密S,生成D。
这个功能很好,除了一个问题:因为它本质上是一个 PBKDF,如果你丢失了密码,你就会丢失数据。起初这是可以接受的,因为可以重建数据;然而,最终用户抱怨必须在管理员密码重置后重建他们的用户帐户(这实际上使加密数据无效)使得它变得不那么重要了。
因此,我需要在现有方案之上实现一些允许管理数据恢复和/或密码重置的东西。我想出了以下内容;请评论:
密码检索/管理员重置:
- 更改用户密码时,客户端软件另外从服务器检索一个通用的 2048 位 RSA 公钥K1。
- 客户端使用K1(和适当的填充方案)来加密C1,产生E。
- 客户端将E与其他用户数据一起传输,这些数据由服务器存储在 DB 中
- 当需要密码恢复时,管理员向服务器进行身份验证,并为用户请求S和E以及K1。
- 管理员还从离线的物理安全存储中获取私钥K2 。
- 管理员使用K2解密E,产生C1。
- 管理员使用C1解密S产生D。
- 管理员为用户选择一个新密码,并获得一个新的C / C1 / C2,然后生成S和E,与客户端通常的方式相同。
- 管理员将U、C2、S和E传输到服务器,服务器将C2加密为新的H并保持U、H、S和E。
- 管理员将新密码离线或以其他方式安全地传输给用户以防止观察,并将其K2的源返回到其安全的物理存储。
优点:
- 显然,它解决了问题;管理员可以重置丢失或忘记的密码。
- 数据仍然是安全的;没有信息通过线路传输或存储在数据库或程序代码中,可用于以该形式获取敏感数据;在不知道密码的情况下,攻击者必须破解 AES-256 加密或使用 OAEP 破解 RSA-2048 以获得第三方凭据。
- 虽然密码是可重置的,但它们永远无法恢复;管理员永远不会看到或知道用户最初选择的明文密码。该密码是用户的,并且是他们自己的(管理员创建的密码可以被视为“临时”,因此需要在使用一次后更改)。
- 如果管理员出于任何原因无法访问用于加密用户基于密码的对称密钥C1的密钥对的特定私钥,他们仍然可以退回到“吹走并重新创建它”恢复用户帐户的方法。
缺点:
- 附加信息必须保持安全;私钥K2。这不是人类可消费的信息,因此必须以数字形式存储;因此,密钥存储必须是物理隔离和安全的,类似于(但可能不如)CA 证书生成的私钥。
问题是,有什么我遗漏的东西会使这个附加的计划不适合或不可行吗?