我正在构建一个 Web 应用程序,它将使用 DropBox API 将数据保存到用户文件夹。该站点有 2 个部分:一个 ASP.NET MVC 前端和一个 Windows 服务。目前,我正计划将授权请求中的 oauth 字符串和用户 ID 转储到数据库,并在服务和网站调用中使用它,但我应该如何存储这些信息?我应该加密还是不加密?如果是这样,有什么建议吗?例如,如果数据库是加密的,我如何存储加密密钥?
1 回答
您想始终访问用户的投递箱帐户还是仅在他们登录到您的系统时访问?我假设是前者,因为您想存储 o-auth 令牌。在这种情况下,请参阅下面的加密讨论,了解为什么您不能真正加密它。但是,我建议您采取更安全的路线,并且仅在用户登录时或之后不久访问下拉框(即不存储持久性身份验证令牌)
安全的方法
当用户登录时,从保管箱中获取一个 oauth 令牌,使用它来执行他们想要的任何操作,并在必要时在注销后保留它以继续执行任务(后台同步或其他东西)。但是,一旦最后一个任务完成,请删除该令牌。这意味着,如果您的服务器受到威胁,则只有登录用户或最近注销的用户会被暴露。它是一种缓解,但它是你能得到的最好的。
我相信您可以使用 o-auth 做到这一点,而无需每次都明确提示用户输入新令牌。如果没有,我知道您可以使用 opendID 来完成,尽管我可以看到 drop box 不允许这样做。
最后,如果这些都不起作用,您可以将 o-auth 密钥永久加密存储在从用户密码派生的密钥下,例如 PBKDF2(大约 5000 次迭代)。当他们登录时,你解密它,使用它,然后删除明文副本。这样做的缺点是 1) 密码重置需要一个新的 o-auth 令牌,因为您不再拥有他们的密钥;2) 用户必须自己登录到您的站点并给您一个密码,以便您可以派生密钥。他们不能使用 openid。
加密
如果您想持续访问 oauth 令牌,则无法真正进行有意义的加密。如您所说,您将密钥存储在哪里?对于 Web 服务,没有好的答案。对于最终用户系统,答案是从您不得存储的用户密码中获取密钥(这是 lastpass 所做的)。您不能这样做,因为即使最终(wepapp)用户未登录,您也希望能够访问数据。
好的,系统管理员的密码呢?好吧,由于服务器一直在运行,这是毫无价值的,因为妥协仍然会泄露密钥。更糟糕的是,重新启动会关闭您的应用程序,因为它需要系统管理员的密码来解密其数据,而且当系统在凌晨 3 点崩溃时,它们不太可能是他们的。
他们制作了存储密钥并使用它们执行加密操作的硬件安全模块,因此攻击者可以获得密钥,因为它永远不会离开 HSM。但是,攻击者可以只要求 TPM 解密 o-auth 字符串。你能做的最好的就是限制这个速率,这样一次攻击每小时只能获得 1000 个令牌(显然这个速率需要大于合法使用)。鉴于 HSM 很昂贵,并且因为您需要专用系统而使托管变得昂贵,所以这是不值得的。
在理想情况下,您将使用TPM来保存密钥,并且仅在系统未受到威胁时才释放数据。不幸的是,TPM 目前只支持验证是否加载了正确的程序(例如引导加载程序,然后是内核,然后是用户空间程序)。如果该程序在加载后受到威胁,他们什么也不做,这就是这里的威胁向量。这可能会在未来 5 到 10 年内发生变化,但这对您现在没有帮助。