1

想象一下这种情况:您的用户向您提供他们的凭据(用户名/密码)以访问第三方服务。因此,您必须在连接到服务时生成这些凭据,而不能只存储加盐哈希。

环境是 Grails,以 psql 作为 DB。从程序员的角度来看,理想情况下,用户/密码仍然是域对象的一部分(因此它们易于使用)。

安全存储它们的最佳做法是什么?

4

1 回答 1

2

*(我不是安全或加密专家;这是我根据阅读和研究得出的理解,但与权威建议相去甚远。请咨询网络应用安全专家的建议并进行适当的安全审核。)*

您真正能做的最好的事情是让您的应用程序在用户未主动登录时无法解密它们。

使用部分基于用户的原始未散列密码的密钥加密凭据。当然,您永远不会存储用户密码以在您的系统上登录您的服务,因此您只能在身份验证期间访问它的一小段时间(而且只有在那时,因为网络还没有赶上 90 年代中期并采用理智的质询-响应身份验证方案)。您可以在用户登录时解密保存的第三方服务凭据,并将它们存储在用户的易失性服务器端会话中。

对于加密密钥,您可以使用您为每个(用户、3rd-party-credential)对随机生成的大盐值对用户名和用户原始密码进行哈希处理,并与加密的凭据一起存储。盐应该不同于用于存储散列密码的盐。

这远非理想,并且存在各种问题 - 但是在用户的会话到期或他们记录我们并且您清除他们的会话后,将无法访问凭据。

这也意味着您的应用程序在他们未主动登录时无法代表他们采取行动,根据您的要求,这一限制可能会成为您的障碍。

较弱的选项是为所有用户凭据设置一个密钥,该密钥由系统管理员在重新启动应用程序时手动输入。该密钥必须存储在内存中,但它至少不位于磁盘或数据库中,因此窃取您数据库转储的人将难以解密存储的凭据。

如果攻击者找到一种方法来欺骗您的应用程序在解密后泄露这些域对象,或者让它让他们冒充该用户,让它代表另一个用户在 3rd 方服务上执行操作等,这两个选项都不会帮助您. 不过,它至少可以防止数据库转储和类似攻击被盗。

pgcrypto进一步的建议:与其在数据库中使用加密,不如在应用程序端进行。这意味着数据库永远不会看到解密数据所需的密钥材料;它永远不会泄露到数据库日志中、被嗅出pg_stat_activity等。

于 2013-04-23T10:34:12.103 回答