如何使用OAuth2身份验证保护私有数据?

时间:2014-09-13 13:56:25

标签: security authentication encryption oauth-2.0

我正在建立一个网站,使用Google的OAuth2界面进行用户身份验证。该网站将存储与每个用户相关的私人数据 - 我计划对其进行加密。

如果我为网站实现了自己的身份验证方法,我可以轻松地从用户的凭据(包括用户的密码)中获取密钥,从而可以强制保护每个用户的数据。但是使用OAuth2,我相信我只能接收一个访问令牌,在一段时间内授予该用户权限 - 问题是访问令牌值会随着时间的推移而改变。

有没有办法OAuth2可以为我提供一个与用户绑定的不可变秘密,我可以使用它来从中获取安全密钥?或者是否存在使用OAuth2创建安全持久密钥的其他方法?

---编辑---

在回答问题和评论时,需要考虑以下几点:

  • 所有用户信息应始终受到强加密和用户身份验证的保护 - 我们阅读了很多关于网站和新闻的新闻文章的原因。数据库黑客是因为开发人员说“我们真的需要保护它”,然后回答“不 - 因为没有人,但我们将能够访问数据库,安全性很难,等等”。黑客下载数据库etviolá。信用卡,电子邮件地址,电话号码,密码,您的名字,然后就会受到损害。
  • 只有两个真正的秘密 - 一个是存储在某人头脑中的密码,另一个是只有授权用户才能访问的强随机值(如物理令牌)。如果您认为安全密钥可以单独从电子邮件地址派生,或者秘密需要存储在数据库中,那么您并不真正了解安全性。

我想我想要发现的是OAuth提供商是否可以向OAuth客户端提供与用户和客户端安全链接的不可变值 - 实际上,这将是一个只能由OAuth提供商解锁的密钥用户秘密(其身份验证密码)和客户端密钥(在OAuth协议中使用)的组合。然后,客户端可以使用此值为用户的数据提供合理的安全级别。

当然,这种实现并非完美,因为滥用,但正确实施,可以提供合理的方法来保护数据,同时仍然使用OAuth方案的良好实践。

5 个答案:

答案 0 :(得分:0)

令牌的要点是您可以使用令牌从Google获取有关用户的信息。在初始身份验证期间,您将告诉用户和Google,您要访问有关该用户的特定信息:

https://developers.google.com/+/api/oauth

假设用户允许您访问他们的信息,例如他们的电子邮件地址,您可以从谷歌获取他们的电子邮件地址。获得电子邮件地址后,您可以为其用户生成密钥,将其存储在用户表中,并使用它来加密其数据。然后,当他们再次登录时,您可以查找他们的电子邮件地址并找到他们的密钥。

对于不可变信息是否特定需要'秘密'?或者它只是识别用户的关键?

如果您存储的信息是真正的私密信息,并且您希望将其设置为无法访问用户的数据,那么您只需为用户存储加密的blob即可。一旦用户下载了他们的数据,他们就可以使用他们的密钥来解密数据客户端。

答案 1 :(得分:0)

我的第一个问题是:为什么要从某些令牌中获取加密密钥?

令牌和加密密钥可以保持独立,并且可以与由唯一ID标识的用户相关联。用户身份验证可以通过凭据或开放式身份验证或其他方式以您需要的任何方式完成。但是,一旦用户通过身份验证,您的解密API就可以获取与经过身份验证的用户关联的解密密钥,并执行其所拥有的任何解密。

通过这种方式,您可以允许用户将多个开放ID帐户绑定到与Stackoverflow类似的相同用户。我可以将我的yahoo,facebook和google帐户与我的Stackoverflow用户关联,并可以与任何这些提供商登录。我可以随时解除这些帐户的关联。但这不会影响我的Stackoverflow配置文件和数据。

因此,从不稳定且不断变化的事物中导出密钥并不是一个好主意。相反,将它们分开。

答案 2 :(得分:0)

如果我为网站实施了自己的身份验证方法,则可以轻松地从用户的凭据中获取密钥

此架构有一个可怕的弱点-如果用户忘记/重置其凭据,则密钥将永远丢失

OAuth2是否可以为我提供与用户相关联的不可变秘密,我可以使用该秘密来获取安全密钥?

OAuth2是授权协议。它无意向您提供任何用户机密。

Google的OAuth2应该提供一个user info service返回用户名(电子邮件)和一些ID(子)。

但是这些只是身份信息,而不是任何秘密。而且,混合用户凭据并不是一个坏主意(如上所述),使用外部IdP(google),您将无法访问凭据。

那又是什么?

我的建议:

如果您真的想使用用户提供的密钥对用户数据进行加密,请让用户提供密钥或由用户本身(或使用用户的公共密钥?)对数据加密密钥进行加密。用户必须知道,如果此机密丢失,则数据将不可访问。从长远来看,这很安静。一些DMS系统使用这种方法来加密存储的敏感文档。

如果要加密静态数据(在服务器,数据库上),则可能具有特定于应用程序的密钥,恕我直言最好将其存储在其他位置(密钥库,密钥管理服务等)。确实确实存在不同的风险状况(您必须保护密钥,..),但对于用户而言却更为方便。结合其他安全措施,通常这已经足够好(即使大型企业也不需要单独的密码来加密您的信用卡号或电子邮件)

答案 3 :(得分:-1)

您需要的是每个用户的常量安全(随机)密钥,您可以从提供OAuth2端点的身份验证服务(在本例中为Google)获取。

OAuth2协议本身不提供此类值 - 身份验证服务器使用不常量的生成值。但OAuth2并不禁止从资源服务器(以及用户ID,电子邮件等)提供此值。因此,基本上OAuth2可以让您以您想要的方式保护数据,但您目前使用的Google不会提供此类常量随机值。

另请注意,如果您允许用户关联少数帐户(例如Google和Facebook),这将无效,因为他们会提供不同的随机密钥。

如果您从凭据中获取秘密,这也意味着重置密码会重置用户帐户。

此外,如果以这种方式加密电子邮件等数据,则无法在没有当前登录用户的情况下解密它们。所以通过电子邮件发送简报几乎是不可能的。您也无法在SQL中查询数据。

我只能建议一些对策:

  • 根本不存储敏感数据,也不存储哈希值。密码必须经过哈希处理,而不是加密。不要存储CC号码,存储代表它们的令牌。
  • 使用密钥加密,存储在另一个数据源中。这至少增加了一些安全性 - 攻击者不仅必须获得数据库副本,还必须获得加密密钥。
  • 由于数据已加密,因此不再需要将其存储在数据库中。您可以将加密数据存储在文件或其他来源中,它比DB更安全(没有SQL注入等风险)

答案 4 :(得分:-1)

我一直有同样的问题。到目前为止,我找不到一个安全的方法。

基本上,我们需要一个每站点随机生成的秘密,只提供隐式流,可用于派生凭证访问系统和解密数据。

因为我想保护自己的数据,所以我可以用两种方式编写客户端来解密/散列秘密,一种是检索数据,另一种是解密数据。

唉,事实并非如此。

我可以从oAuth基本范围内的事物中获取凭据,并保护数据免受 me 的影响,但这会使用户对跨站点漏洞敞开大门,此外,还可以识别个人身份信息是一个可怜的秘密。

我得到的最好的方法是使用隐式流oAuth2来获取用户的电子邮件地址,随机生成客户端密钥,并强制用户通过电子邮件发送秘密(作为恢复密钥),然后将密钥存储在localStorage中。 Salt / Hash秘密+ oauth范围变量,以获取访问,加密和解密数据所需的凭证客户端(因此用户必须登录)。

如果用户清除了localStorage,他们需要点击恢复邮件中的链接,将秘密放回localStorage。

这将漏洞的范围放回客户端,但是对公共计算机有抵抗力(必须知道最后登录的是谁,并且能够访问localStorage令牌),允许恢复,并且弱需要用户登录。仍然容易受到插件注入攻击和物理访问的影响+了解用户。

更新:我决定使用一些oAuth扩展(hello.js,文件夹API)将密钥作为文件存储在用户帐户中。它需要一些权限和一些API来实现,但似乎是可行的。