我有一些看似矛盾的要求:
( 1)我们从第三方获取用户的内容;某些用户的内容应在休息时被加密存储,以符合要求。
2)用户应该能够通过安全的webapp/api解密和显示他们的内容
3)给定帐户上有许多用户,所有用户都应该能够解密和查看对方的内容(意味着共享密钥)。
4)后端工作进程应该能够随时解密和重新处理用户的内容,如果我们想(例如)改进我们的分析
如果有必要,我们可以牺牲#4 (或者让用户进行身份验证来允许它)。
当然,我不想将加密密钥存储在任何地方的明文中。将其存储在用户级别是最方便的,使用从密码中提取的散列PBKDF2 2‘加密--但如果他们忘记密码并需要重置密码(因为我们现在不能再派生密钥了),就会引入一个繁琐的工作流。
我也不能仅仅使用密码,因为对已经加密的内容的访问应该在更改密码请求中存活下来。当然,我们也不能访问异步后端工作任务中的明文密码。
是否有一种普遍接受的方法来做到这一点?例如,我是否可以使用某种2FA-ish工作流来检索一个用户秘密,我从不在本地存储,但哪一个用于保护密钥?
发布于 2017-02-09 00:53:14
通常的方法是为每个帐户使用一个主密钥,用于进行实际的加密/解密/完整性检查,但它从不存储在任何地方的纯文本中。这个主密钥应该使用安全的随机数生成器来生成,不应该有任何方法来检索它的纯文本值。
您可以使用从用户凭据派生的每个用户密钥对主密钥进行加密(您可以使用密钥派生函数--如果可能的话使用比PBKDF2更强的东西,如sort或argon2 --在用户的密码上使用,或者要求用户拥有其他类型的加密密钥,比如TLS客户端证书)。因此,每个用户都为自己的帐户存储自己的主密钥加密副本。这些加密的主密钥可以存储在服务器上,因为如果没有每个用户的密钥来解密它们,它们是无用的。每个用户的密钥从未以任何形式存储在服务器上;它们要么由客户机直接提供,要么从客户端提供的数据(例如密码)中临时派生出来,然后使用,然后删除。
如果有必要(对于您的#4),您还可以使用其他密钥加密每个帐户的主密钥,比如后台工作进程。当然,您只是推卸了一步的责任;为该员工生成密钥的密钥/证书存储在哪里?它是如何保护的,以至于攻击者不能直接抓取它,解密相应的主密钥(S),然后进城?
密码重置确实会变得有些棘手。仅仅更改密码很容易:获取旧密码,解密主密钥,用新密码重新加密它,并将新加密的主密钥保存回数据库。当旧密码未知时重新设置密码比较困难。除了“您不能丢失所有加密的数据”(我认为这是不可接受的)之外,通常的选项是给用户一次使用的恢复密钥,这些密钥太长,无法用于正常密码,但可以用于在需要时解密主密钥(这意味着您将拥有一个使用标准的每个用户密钥加密的主密钥和一个使用用户的恢复密钥加密的主密钥),并要求一个用于重新设置密码的恢复密钥,或者要求其他被授权访问该数据的用户为正在重置其密码的用户提供数据担保,并使用凭单用户的凭据来解锁主密钥的凭证用户副本,然后用重置用户的密钥对其进行加密并存储新加密的主密钥(因为每个“帐户”有多个用户,只要没有用户同时忘记他们的密码,这就足够好了)。
发布于 2017-02-09 00:49:02
在您的web服务器上运行一个专用的加密服务/恶魔怎么样?
该服务将使用一个主密码(您知道),并需要在服务器重新启动时重新输入。您可以使用密钥派生函数创建内存中的加密密钥。
然后,数据可以由web应用程序和后台办公人员进程使用的服务随意加密或转换。
https://security.stackexchange.com/questions/150777
复制相似问题