移动应用中的OAuth秘密

Fel*_*xyz 130 security iphone mobile android oauth

使用OAuth协议时,您需要从要委派的服务获取的秘密字符串.如果您在Web应用程序中执行此操作,则可以将秘密存储在数据库或文件系统中,但在移动应用程序(或桌面应用程序)中处理此问题的最佳方法是什么?

在应用程序中存储字符串显然不是很好,因为有人可以很容易地找到并滥用它.

另一种方法是将其存储在您的服务器上,并让应用程序在每次运行时获取它,而不是将其存储在手机上.这几乎一样糟糕,因为您必须在应用程序中包含URL.

我能想到的唯一可行解决方案是首先正常获取访问令牌(最好使用应用程序内部的Web视图),然后通过我们的服务器路由所有进一步的通信,这将秘密附加到请求数据并进行通信与提供者.再说一次,我是一个安全菜鸟,所以我真的很想听听一些知识渊博的人对此的看法.在我看来,大多数应用程序都没有这么长时间来保证安全性(例如,Facebook Connect似乎假设您将秘密放入应用程序中的字符串中).

另一件事:我不相信最初请求访问令牌的秘密,所以可以在不涉及我们自己的服务器的情况下完成.我对么?

Zac*_*ing 34

是的,这是我们面对的OAuth设计的一个问题.我们选择通过自己的服务器代理所有呼叫.对于桌面应用程序,OAuth并未完全被刷新.没有改变OAuth,我找到的问题没有完美的解决方案.

如果您考虑并提出问题,为什么我们有秘密,主要是为了提供和禁用应用程序.如果我们的秘密被泄露,那么提供商只能真正撤销整个应用程序.由于我们必须在桌面应用程序中嵌入我们的秘密,因此我们有点紧张.

解决方案是为每个桌面应用程序提供不同的秘密.OAuth不会使这个概念变得容易.一种方法是让用户自己创建一个秘密,并将自己的密钥输入到您的桌面应用程序中(一些Facebook应用程序做了类似的事情很长一段时间,让用户去创建Facebook来设置他们的自定义测验和废话).这对用户来说不是一次很棒的体验.

我正在制定OAuth授权系统的提案.我们的概念是使用我们自己的秘密密钥,我们可以从我们自己的桌面客户端(基本上每个桌面应用程序一个)发出我们自己的委托秘密,然后在授权过程中我们将该密钥发送到顶级提供商回电给我们并与我们重新验证.这样我们就可以撤销我们发给每个桌面客户端的秘密.(借用SSL的很多工作方式).整个系统对于增值网络服务也是完美的,它将调用传递给第三方网络服务.

如果顶级提供者提供API来生成和撤销新的委托机密,则也可以在没有委托验证回调的情况下完成该过程.通过允许Facebook应用程序允许用户创建子应用程序,Facebook正在做类似的事情.

网上有一些关于这个问题的讨论:

http://blog.atebits.com/2009/02/fixing-oauth/ http://groups.google.com/group/twitter-development-talk/browse_thread/thread/629b03475a3d78a1/de1071bf4b820c14#de1071bf4b820c14

Twitter和Yammer的解决方案是一个身份验证引脚解决方案:https : //dev.twitter.com/oauth/pin-based https://www.yammer.com/api_oauth_security_addendum.html

  • 只是好奇:你如何确定调用你的代理服务器的东西是合法的? (5认同)

Dic*_*rdt 18

使用OAUth 2.0,您可以将密钥存储在服务器上.使用服务器获取一个访问令牌然后移动到应用程序,您可以直接从应用程序调用该资源.

使用OAuth 1.0(Twitter),需要秘密进行API调用.通过服务器代理呼叫是确保秘密不受损害的唯一方法.

两者都需要一些机制,您的服务器组件知道它是您的客户端调用它.这通常在安装时完成,并使用特定于平台的机制在服务器调用中获取某种应用程序ID.

(我是OAuth 2.0规范的编辑)

  • 你能详细说明"获取某种应用程序ID的平台特定机制"吗?服务器组件如何验证客户端的身份?我认为这可以通过客户端配置来完成.例如,为每个客户端部署一个新的唯一SSL证书.你是这个意思吗?如果它比这更复杂,也许你可以参考更深入的写作? (2认同)
  • 我记得一些安全人员在谈论如何做到这一点.有一个操作系统调用返回一个签名的令牌,然后您可以将其发送到您的服务器并进行验证.对不起,我没有具体细节.这是一个错误,可以使用一些很好的例子. (2认同)
  • @DickHardt,但是在此场景中,您如何确保移动应用程序确实是您的应用程序而不是欺诈性应用程序? (2认同)

Jay*_*esh 10

一种解决方案可能是将OAuth秘密硬编码到代码中,但不能作为普通字符串.以某种方式对其进行模糊处理 - 将其拆分为段,通过偏移移位字符,旋转它 - 执行任何或所有这些操作.破解者可以分析您的字节代码并查找字符串,但是混淆代码可能很难弄清楚.

这不是一个万无一失的解决方案,而是一个廉价的解决方案.

根据漏洞利用的价值,一些天才破解者可以更加努力地找到您的密码.您需要权衡因素 - 前面提到的服务器端解决方案的成本,激励破解者花费更多精力来查找您的密码,以及您可以实现的混淆的复杂性.

  • 混淆根本不是安全问题.这比没有安全性更糟糕,因为它给开发人员带来了错误的安全感.https://en.wikipedia.org/wiki/Security_through_obscurity (8认同)
  • "混淆根本不是安全性.这比没有安全性更糟糕,因为它给开发人员带来了错误的安全感." 废话.没有人说混淆会带来良好的安全性.但是,如果我要用我的apk分发OAuth秘密,那么混淆肯定会更好.混淆是谷歌在应用程序中存储密钥/秘密时所建议的.如果不出意外,这些措施会让随意的黑客陷入困境,这总比没有好.像你这样的毯子语句将不完美的安全性等同于没有安全性.这根本不是真的.不完美只是不完美. (8认同)
  • 只需一个用户付出努力,然后发布或分享您的秘密即可.一旦你的秘密被淘汰,你的服务被滥用的风险完全被关闭,这完全超出了你的控制范围. (7认同)
  • 混淆无济于事,因为无论您进行多少转换或编码,您仍然会一起构建密钥并使用它来构建您的 API 请求。在正确的位置动态挂钩 API 以在 HTTPS 加密之前转储您发送的请求是相当简单的。所以请不要在您的应用程序中嵌入密钥,除非确实没有可能的替代方案。 (3认同)

Gud*_*ain 6

不要将秘密存储在应用程序中.

您需要有一个服务器可以通过https(显然)由应用程序访问,并将密码存储在其上.

当有人想通过您的移动/桌面应用程序登录时,您的应用程序将简单地将请求转发给服务器,然后该服务器将附加秘密并将其发送给服务提供商.然后,您的服务器可以告诉您的应用程序是否成功.

然后,如果您需要从服务(Facebook,谷歌,推特等)获取任何敏感信息,应用程序会询问您的服务器,只有正确连接后,您的服务器才会将其提供给应用程序.

除了将其存储在服务器上之外,实际上没有任何选择.客户端没有任何东西是安全的.

注意

也就是说,这只会保护您免受恶意客户端的攻击,但不能防止客户端遭到恶意攻击,而不是客户端攻击其他恶意客户端(网络钓鱼)......

OAuth是一种比桌面/移动设备更好的浏览器协议.


Joh*_*ter 6

授权代码授予类型有一个新的扩展,称为代码交换证明密钥 (PKCE)。有了它,您就不需要客户端机密了。

PKCE (RFC 7636) 是一种保护不使用客户端机密的公共客户端的技术。

它主要由本机和移动应用程序使用,但该技术也可以应用于任何公共客户端。它需要授权服务器的额外支持,因此仅在某些提供程序上受支持。

来自https://oauth.net/2/pkce/

有关更多信息,您可以阅读完整的RFC 7636此简短介绍