移动应用中的OAuth秘密

问题描述 投票:128回答:13

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

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

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

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

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

iphone android security mobile oauth
13个回答
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



0
投票

Facebook并没有严格执行OAuth,但他们已经实现了一种方法,你不要将你的秘密嵌入你的iPhone应用程序中:https://web.archive.org/web/20091223092924/http://wiki.developers.facebook.com/index.php/Session_Proxy

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


0
投票

授权代码授权类型有一个新的扩展,名为Proof Key for Code Exchange(PKCE)。有了它,您不需要客户机密。

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

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

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

有关更多信息,您可以阅读完整的RFC 7636this short introduction


-1
投票

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

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

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


18
投票

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

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

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

(我是OAuth 2.0规范的编辑)


10
投票

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

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

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


5
投票

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

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

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

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

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

注意

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

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


2
投票

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

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


2
投票

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

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


0
投票

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

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


0
投票

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

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

YourApp(yourapp.appspot.com) - 与谷歌无关

等等

如果您使用自定义方案拦截回调,它会从您提供的回调网址中使用的域名/主机名中获取<some-site>,这可以是Android上的任何内容。因此,如果您使用“匿名”访问权限或您的消费者机密被泄露,那么任何人都可以编写一个消费者,欺骗用户访问您的gae应用程序。

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

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

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


0
投票

我还试图提出一个移动OAuth身份验证解决方案,并将秘密存储在应用程序包中。

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

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

那会有用吗?

© www.soinside.com 2019 - 2024. All rights reserved.