使用 cookie 将加密的第三方密码安全地存储在 DB 中
Using cookies to securely store encrypted third-party passwords in DB
显然,存储任何类型的第三方凭证都是一项重大风险,我想尽可能避免。但是,我对它如何相对安全有一个想法,我想就此策略发表一些意见:
MySite 允许用户使用用户名和密码(或 Facebook,等等)注册!
如果该用户也在网站 AllTheData.com(此处称为 ATD)上注册了用户名和密码,他们可以通过 HTTPS 给我。
MySite 收到 ATD 的第三方凭据并做两件事:创建一个新的加密密钥,它存储在用户的 cookie 中,并使用该密钥加密用户名和密码并存储它们数据库中的加密值。
AllTheData.com 的数据库可能如下所示:
| User | Password
| JohnDoe@gmail.com | p4ssw0rd_hashed
MySite 的数据库现在看起来像这样:
| User | Password | ATD_username |ATD_pass
| JohnDoe@gmail.com | another_p4ssw0rd_hashed| ct5lHMGymedITfElVA...|BHJCS38DkG7Zg0...
并且用户的浏览器有一个带有密钥的 cookie:
MySite_key: E3iKZxk2ZDD4EUb*fH$X6Mz5BO^iQeOM&V$lB0WAk4&WAB#A4QB8Yn7
现在,当我需要访问该服务时,我从我的数据库中提取加密值,并从他们的请求中提取 cookie,然后我就可以访问服务器了!当然,如果他们的 cookie 已过期或者他们已经清除了它们或更换了计算机或其他任何东西,那么我必须再次询问 :( 但如果这意味着我不必以普通方式存储凭据,那是值得的!
我在这里做错了什么吗?这个方案有什么明显的问题吗?
谢谢!
我同意 CBroe 的评论。有比强迫您的用户放弃他们宝贵的凭据更好的方式与第三方进行交互。我建议研究 OAuth 之类的东西。它为您的用户提供了很多很棒的功能:
- 他们只向 ATD 出示他们的 ATD 凭据
- ATD 可以让他们控制您的系统可以为他们执行哪些数据或操作。用户有权随时撤销对您系统的访问权限。
- 您希望与之集成的大多数大型第三方已经 OAuth providers
既然您已经声明 OAuth 不是一个选项,那么在使用您提出的解决方案之前,我会再尝试一个攻击计划。您已经承认您的解决方案非常短暂;一旦用户清除了他们的 cookie,您就要求他们重新登录。如果您调用的服务在登录时创建会话,您可以简单地将用户凭据转发给第三方并临时缓存该服务通常 return 给用户的任何令牌或会话 ID(我认为没有理由存储这在数据库中)。一旦您的用户注销您的系统,您就可以删除该令牌。这使您无法直接存储他们的凭据。这不是一个很大的进步,但这是我首先要追求的。
如果你将它与你的 cookie 加密想法结合起来,我认为你会得到很好的分离。您在服务器上缓存了加密的身份验证令牌,但只有将加密密钥存储为 cookie 的用户才能访问它。就像你说的那样,如果你受到威胁,这会阻止你的服务器向第三方提供访问权限。如果您的 客户端 受到威胁,您实际上得不到任何保护,但我认为这是不可避免的。
如果系统对每个请求都需要凭据,那么我真的看不出更好的方法。您已完成作业,但我看不到更好的解决方案。
虽然这不是允许访问第 3 方系统的最佳方式,但这也不好。
确保 MySite_key
是由加密安全算法生成的,这样攻击者就无法预测它,并尽可能保护此 cookie。如果您的站点存在任何漏洞,cookie 对攻击者来说将变得 非常 有价值。当然,价值多少取决于用户在 ATD 中可以访问哪些数据。
这意味着在您的网站上实施 SSL/TLS,加强 Secure Flag and HTTP Only Flag on the cookie and setting a HSTS policy. Also ensure that your site does not have any session fixation 漏洞 - 如果存在漏洞,攻击者可能能够为其他用户的帐户设置自己的加密密钥。
确保加密算法也足够安全以满足您的需求,例如AES-128。
还要确保您与 ATD 的通信仅结束 SSL/TLS。同样,使用被认为安全且不易受到任何降级攻击的协议和密码套件版本(例如 FREAK)。
显然,存储任何类型的第三方凭证都是一项重大风险,我想尽可能避免。但是,我对它如何相对安全有一个想法,我想就此策略发表一些意见:
MySite 允许用户使用用户名和密码(或 Facebook,等等)注册!
如果该用户也在网站 AllTheData.com(此处称为 ATD)上注册了用户名和密码,他们可以通过 HTTPS 给我。
MySite 收到 ATD 的第三方凭据并做两件事:创建一个新的加密密钥,它存储在用户的 cookie 中,并使用该密钥加密用户名和密码并存储它们数据库中的加密值。
AllTheData.com 的数据库可能如下所示:
| User | Password | JohnDoe@gmail.com | p4ssw0rd_hashed
MySite 的数据库现在看起来像这样:
| User | Password | ATD_username |ATD_pass | JohnDoe@gmail.com | another_p4ssw0rd_hashed| ct5lHMGymedITfElVA...|BHJCS38DkG7Zg0...
并且用户的浏览器有一个带有密钥的 cookie:
MySite_key: E3iKZxk2ZDD4EUb*fH$X6Mz5BO^iQeOM&V$lB0WAk4&WAB#A4QB8Yn7
现在,当我需要访问该服务时,我从我的数据库中提取加密值,并从他们的请求中提取 cookie,然后我就可以访问服务器了!当然,如果他们的 cookie 已过期或者他们已经清除了它们或更换了计算机或其他任何东西,那么我必须再次询问 :( 但如果这意味着我不必以普通方式存储凭据,那是值得的!
我在这里做错了什么吗?这个方案有什么明显的问题吗?
谢谢!
我同意 CBroe 的评论。有比强迫您的用户放弃他们宝贵的凭据更好的方式与第三方进行交互。我建议研究 OAuth 之类的东西。它为您的用户提供了很多很棒的功能:
- 他们只向 ATD 出示他们的 ATD 凭据
- ATD 可以让他们控制您的系统可以为他们执行哪些数据或操作。用户有权随时撤销对您系统的访问权限。
- 您希望与之集成的大多数大型第三方已经 OAuth providers
既然您已经声明 OAuth 不是一个选项,那么在使用您提出的解决方案之前,我会再尝试一个攻击计划。您已经承认您的解决方案非常短暂;一旦用户清除了他们的 cookie,您就要求他们重新登录。如果您调用的服务在登录时创建会话,您可以简单地将用户凭据转发给第三方并临时缓存该服务通常 return 给用户的任何令牌或会话 ID(我认为没有理由存储这在数据库中)。一旦您的用户注销您的系统,您就可以删除该令牌。这使您无法直接存储他们的凭据。这不是一个很大的进步,但这是我首先要追求的。
如果你将它与你的 cookie 加密想法结合起来,我认为你会得到很好的分离。您在服务器上缓存了加密的身份验证令牌,但只有将加密密钥存储为 cookie 的用户才能访问它。就像你说的那样,如果你受到威胁,这会阻止你的服务器向第三方提供访问权限。如果您的 客户端 受到威胁,您实际上得不到任何保护,但我认为这是不可避免的。
如果系统对每个请求都需要凭据,那么我真的看不出更好的方法。您已完成作业,但我看不到更好的解决方案。
虽然这不是允许访问第 3 方系统的最佳方式,但这也不好。
确保 MySite_key
是由加密安全算法生成的,这样攻击者就无法预测它,并尽可能保护此 cookie。如果您的站点存在任何漏洞,cookie 对攻击者来说将变得 非常 有价值。当然,价值多少取决于用户在 ATD 中可以访问哪些数据。
这意味着在您的网站上实施 SSL/TLS,加强 Secure Flag and HTTP Only Flag on the cookie and setting a HSTS policy. Also ensure that your site does not have any session fixation 漏洞 - 如果存在漏洞,攻击者可能能够为其他用户的帐户设置自己的加密密钥。
确保加密算法也足够安全以满足您的需求,例如AES-128。
还要确保您与 ATD 的通信仅结束 SSL/TLS。同样,使用被认为安全且不易受到任何降级攻击的协议和密码套件版本(例如 FREAK)。