移动应用中的OAuth秘密

时间:2009-12-19 21:24:08

标签: iphone android security mobile oauth

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

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

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

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

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

14 个答案:

答案 0 :(得分:34)

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

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

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

我正在制定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

答案 1 :(得分:18)

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

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

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

(我是OAuth 2.0规范的编辑)

答案 2 :(得分:10)

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

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

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

答案 3 :(得分:5)

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

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

如果有人想通过您的移动/桌面应用程序登录,您的应用程序只会将请求转发给服务器,然后该服务器会附加密码并将其发送给服务提供商。然后,您的服务器可以告诉您的应用程序是否成功。

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

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

注意

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

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

答案 4 :(得分:2)

这是值得思考的问题。 Google提供了两种OAuth方法...用于网络应用,您可以在其中注册域并生成唯一密钥,以及使用密钥“匿名”的已安装应用。

也许我在阅读中掩饰了一些内容,但似乎与安装的应用程序共享您的webapp的唯一密钥可能比在官方安装的应用程序方法中使用“匿名”更安全。

答案 5 :(得分:2)

使用OAuth 2.0,您只需使用客户端流程即可获取访问令牌,然后使用此访问令牌对所有其他请求进行身份验证。那你根本就不需要秘密。

有关如何实现这一点的详细说明,请访问:https://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified#mobile-apps

答案 6 :(得分:0)

我没有大量使用OAuth的经验 - 但并不是每个请求不仅需要用户的访问令牌,还需要应用程序使用者密钥和密钥?因此,即使有人窃取移动设备并尝试从中提取数据,他们也需要一个应用密钥和秘密,以便能够实际执行任何操作。

我一直认为OAuth背后的意图是每个拥有mashup的Tom,Dick和Harry都不必清楚地存储你的Twitter凭据。我认为它很好地解决了这个问题,尽管它有局限性。此外,它并没有真正考虑到iPhone的设计。

答案 7 :(得分:0)

Facebook尚未严格执行OAuth,但他们已经实施了一种方法,让您不要将自己的秘密嵌入iPhone应用中:https://web.archive.org/web/20091223092924/http://wiki.developers.facebook.com/index.php/Session_Proxy

至于OAuth,是的,我想的越多,我们就有点儿了。也许this会修复它。

答案 8 :(得分:0)

我同意Felixyz。 OAuth虽然优于Basic Auth,但仍有很长的路要走,才能成为移动应用的理想解决方案。我一直在使用OAuth来验证手机应用程序与Google App Engine应用程序的身份验证。您无法在移动设备上可靠地管理消费者密钥的事实意味着默认情况下使用“匿名”访问。

Google App Engine OAuth实施的浏览器授权步骤会将您带到包含以下文本的页面: “网站&lt; some-site&gt;正在请求访问您在下面列出的产品的Google帐户”

YourApp(yourapp.appspot.com) - 与Google无关

需要&lt; some-site&gt;来自您提供的回调网址中使用的域/主机名,如果您使用自定义方案拦截回调,则可以是Android上的任何内容。 因此,如果您使用“匿名”访问权限或者您的消费者秘密遭到入侵,那么任何人都可以编写一个欺骗用户的用户来访问您的gae应用程序。

Google OAuth授权页面也包含许多警告,这些警告具有3个严重级别,具体取决于您使用的是“匿名”,消费者保密还是公钥。

对于技术上并不精通的普通用户而言,这是非常可怕的事情。我不希望在这种方式中有这么高的注册完成百分比。

此博客文章阐明了消费者秘密如何与已安装的应用无关。 http://hueniverse.com/2009/02/should-twitter-discontinue-their-basic-auth-api/

答案 9 :(得分:0)

我也在尝试为移动OAuth身份验证提供解决方案,并在应用程序包中存储秘密。

一个疯狂的想法只是打击了我:最简单的想法是将秘密存储在二进制文件中,但以某种方式进行模糊处理,或者换句话说,存储加密的秘密。所以,这意味着你必须存储一把钥匙来解密你的秘密,这似乎已经占据了我们的全部圈子。但是,为什么不使用操作系统中已有的密钥,即操作系统不是由您的应用程序定义的密钥。

所以,澄清一下我的想法是你选择一个由OS定义的字符串,哪个是无关紧要的。然后使用此字符串作为密钥加密您的秘密,并将其存储在您的应用中。然后在运行时,使用密钥解密变量,这只是一个OS常量。窥视你的二进制文件的任何黑客都会看到一个加密的字符串,但没有密钥。

这会起作用吗?

答案 10 :(得分:0)

答案 11 :(得分:0)

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

  

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

     

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

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

有关详情,请参阅完整的RFC 7636this short introduction

答案 12 :(得分:0)

这些解决方案均不能阻止坚定的黑客嗅探从其移动设备(或仿真器)发送的数据包以查看http标头中的客户端机密。

一种解决方案可能是拥有动态秘密,该秘密由使用私有2向加密密钥和算法加密的时间戳组成。然后,该服务解密机密并确定时间戳是否为+/- 5分钟。

通过这种方式,即使机密信息被泄露,黑客也最多只能使用5分钟。

答案 13 :(得分:-1)

正如其他人所提到的,将秘密本地存储在设备上应该没有任何实际问题。

最重要的是,您始终可以依赖Android的基于UNIX的安全模型:只有您的应用程序可以访问您写入文件系统的内容。只需将信息写入应用程序的默认SharedPreferences对象。

为了获得秘密,必须获得Android手机的root访问权限。