Android 防止通过身份验证的客户端使用我的API(可能是PGP/GPG?)

Android 防止通过身份验证的客户端使用我的API(可能是PGP/GPG?),android,web-services,public-key-encryption,gnupg,pgp,Android,Web Services,Public Key Encryption,Gnupg,Pgp,我有一个移动应用程序(Android),它可以向我的服务器发出数以万计的RESTfulWebService请求(当然每天) 出于各种原因,特别是我的服务器资源有限(无论是硬件规格还是通过API响应发送到我的应用程序的昂贵授权内容),我希望确保只有我的应用程序能够向我的Web服务发出成功的API请求 我知道这至少在理论上是可能的,至少对于基于Android的系统是如此,因为谷歌有一种方法可以在可信的第三方服务器(例如,你的API服务器)上。我相信它是基于OAuth的,并且与每个安卓设备必须安装的必

我有一个移动应用程序(Android),它可以向我的服务器发出数以万计的RESTfulWebService请求(当然每天)

出于各种原因,特别是我的服务器资源有限(无论是硬件规格还是通过API响应发送到我的应用程序的昂贵授权内容),我希望确保只有我的应用程序能够向我的Web服务发出成功的API请求

我知道这至少在理论上是可能的,至少对于基于Android的系统是如此,因为谷歌有一种方法可以在可信的第三方服务器(例如,你的API服务器)上。我相信它是基于OAuth的,并且与每个安卓设备必须安装的必要的Google帐户相关联

实际上,我最终实现了这个功能,但大约一个月后就放弃了它,因为它需要的是Google Play Services最新版本中提供的
GoogleAuthUtil
机制,而Google Play Services必须安装在用户的设备上(当然,这阻止了我的大多数用户升级)。另一个问题是,一台设备上可能有多个谷歌账户,所以我要么猜哪个是正确的,要么更糟,提示/烦扰用户选择;这些选择是绝对不可能的

我最初的想法是使用某种公钥加密,比如PGP/GPG。在应用程序中包含我的API公钥(要理解它并不意味着安全——毕竟它是一个公钥),然后除了我已经做的对API请求签名的工作之外,我还可以使用API公钥加密整个内容

几天后(今天),我终于有时间坐下来讨论设计和实现细节,我(以及下面的Robert在评论中)很快意识到,由于API的公钥以及其他与签名相关的逻辑理论上可以提取,一个成功的黑客可以很容易地生成“真正的”API请求,我的API服务器将用它的私钥解密,而不是更聪明

我确实在programmers.stackexchange上遇到了这两个问题,比我聪明得多的人在这个问题上给出了一些非常好的答案:

从我收集到的信息来看,我愿意说是的,这在理论上是可能的(只要看看谷歌的
GoogleAuthUtil
OAuth后端验证系统,我在上面链接了这个系统)。然而,正确地实现/维护是非常痛苦的,所以除非你的API是为核发射代码服务的,否则最好尽可能地混淆请求以防止90%的作弊者


如果一个国防部想删除这个问题或标记为一个重复,请随时。OTOH,如果有人想知道同样的事情,也许这会对他们有所帮助--我从没想过在programmers.stackexchange上问这个问题,但我的大部分线索都是在这些问题中找到的。当然,在不太可能的情况下,一位安全专家看到了这一点,并能解释如何相对容易和有效地完成这一点,那也太好了

为什么不在客户端生成公钥/私钥,并使用服务器公钥将客户端私钥发送到服务器。例如,在服务器端使用某种请求标识符存储客户端私钥,并且可以使用客户端公钥对进一步的请求进行加密,以便发送用户凭据(您的服务器上有吗?)

然而,请求可以来自任何类型的客户机,知道您的接口,但至少请求来自具有有效凭据的用户,否则它们将失败(仍然必须获得资源来处理错误的请求)


这有意义吗?我对这一主题非常陌生,但我也读过很多文章,但没有接触到真正定义良好的解决方案。

如果我反编译你的应用程序并提取公钥以及使用它的相关代码,你会怎么做?你永远无法阻止在应用程序级别使用API,只是通过混淆使其变得更难。我已经对此进行了很多思考,我刚刚想到了这一点(获取API的公钥[我从未认为这是安全的——公钥应该是公共的!),并生成“真正的”API调用),所以我来这里看看社区能提供什么。我不得不说,我非常不同意你的观点,即永远不能阻止确保服务器端API请求来源(例如应用程序)的真实性。毕竟,这是使用SSL的原因之一:要(合理地)确定与您交谈的计算机是他们声称的计算机。由于评论有限制,如果您想向像我这样的安全新手详细说明和解释为什么您是正确的;无法阻止API仅由授权应用程序使用。我理解我在这个问题上的主张不会起作用,但Android有一个系统,可以让你在自己的可信服务器上验证你的应用程序的API请求。事实上,我用了几个月,但它需要用户登录到他们的谷歌帐户,更糟糕的是,我不得不猜测使用哪个帐户。我想我会研究PGP/GPG签名;希望在那个方向?在做了更多的研究后更新了这个问题。“我认为你是对的,@Robert,也许最好只是尽可能地混淆。我个人在寻找Java的实用解决方案