Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Security 如何在数据库上安全地存储用户名/密码(散列不会)_Security_Postgresql_Grails_Passwords_Grails Plugin - Fatal编程技术网

Security 如何在数据库上安全地存储用户名/密码(散列不会)

Security 如何在数据库上安全地存储用户名/密码(散列不会),security,postgresql,grails,passwords,grails-plugin,Security,Postgresql,Grails,Passwords,Grails Plugin,想象一下这种情况:您的用户为您提供了访问第三方服务的凭据(用户名/密码)。因此,当连接到服务时,您必须生成这些凭据,您不能只存储一个盐散列 环境是Grails,psql是DB。从程序员的角度来看,理想情况下,用户/密码仍然是域对象的一部分(因此它们易于使用) 安全存储它们的最佳做法是什么 *(我不是安全或加密专家;这是我根据阅读和研究得出的理解,但远不是权威建议。请咨询web应用安全专家的建议,并进行适当的安全审计。)* 你能做的最好的事情就是让你的应用程序在用户没有主动登录时无法解密它们 使用

想象一下这种情况:您的用户为您提供了访问第三方服务的凭据(用户名/密码)。因此,当连接到服务时,您必须生成这些凭据,您不能只存储一个盐散列

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

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

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

你能做的最好的事情就是让你的应用程序在用户没有主动登录时无法解密它们

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

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

这远远不够理想,并且存在各种各样的问题,但是在用户会话过期或者用户登录我们的会话并清除他们的会话后,将无法访问凭据

这也意味着你的应用程序不能在他们没有主动登录的情况下代表他们行事,根据你的要求,这一限制可能会阻碍你的表现

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

如果攻击者找到一种方法来欺骗你的应用程序,使其在解密后暴露这些域对象,或者让其模拟该用户,让其代表另一用户在第三方服务上执行操作,等等,则这两种方法都不会对你有帮助。它至少可以防止数据库转储被盗和类似的攻击,不过


还有一个建议:不要在数据库中使用
pgcrypto
加密,而是在应用程序端进行。这意味着DB从未看到解密数据所需的密钥材料;它永远不会泄露到数据库日志中,从
pg_stat_activity
中嗅出,等等。

我猜第三方服务不会提供良好的、可撤销的API密钥/基于秘密的访问?顺便说一句,如果你的应用程序能够解密/解码此凭据,那么拥有你应用程序完全访问权限的黑客也可以这样做(只需使用您现有的代码)@CraigRinger正确,这是一个不完美的解决方案(如下所述),但其中一个选项是使用Jasypt加密域中的字段:感谢您的精心贡献。您的第一个想法很棒…但不幸的是,对于我们来说,我们需要在用户未登录时使用凭据。第二个建议是到目前为止我得到的最好建议…谢谢!