如何唯一标识您的 Android 应用程序以获取 REST API

Posted

技术标签:

【中文标题】如何唯一标识您的 Android 应用程序以获取 REST API【英文标题】:How to uniquely identify your Android app for rest API 【发布时间】:2015-11-19 09:21:47 【问题描述】:

有没有办法在 Java 代码中唯一标识我的 android 应用?也许是包名和其他东西的某种组合?我知道有一种方法可以识别唯一的 Android device,但这不是我想要的。

我希望能够唯一标识我制作的我的 Android 应用,以便我可以将该信息传递给我自己的私有 RESTful API。这将允许我验证呼叫来自我的 Android 应用程序,而不是另一个未经授权的应用程序。我希望我的 RESTful API 仅适用于我制作的应用程序,因此没有人可以欺骗它或未经授权访问它。

或者这是不可能的?我只是想知道像 Snapchat 这样的应用程序是如何拥有自己的登录名的,而没有。显然有什么东西在保护它。

【问题讨论】:

“这将允许我验证呼叫来自我的 Android 应用程序而不是另一个”——不,它不会,因为任何人都可以将相同的信息传递给您的 REST Web 服务.例如,您可以将包名称和公共签名密钥的 SHA256 散列放在 REST Web 服务的 URL 中。其他任何人都可以通过检查 Web 流量来找到这些值,并将它们放在 REST Web 服务的 URL 中的相同位置。 @CommonsWare 即使你使用了 https? 一般来说,是的。有许多可用于 Android 的代理。许多可以拦截HTTPS。现在,理论上,如果您放入大量自己的证书验证逻辑,您可能会让某人成功窥探 HTTPS 流量有点困难。但是,通过对应用程序进行逆向工程,他们可以禁用证书验证逻辑,或者只查看您如何组装 Web 服务调用。 @CommonsWare 所以基本上你所说的是没有办法将你的android应用程序保护到你自己的restful api?既然.apk是可以反编译的,你最多只能把证书验证逻辑弄得很复杂,希望没有人聪明到能破译它?那么 Snapchat 或其他应用程序是如何做到的呢? “所以基本上你的意思是没有办法保护你的安卓应用到你自己的restful api?” - 这完全取决于您对“安全......对您自己的宁静 api”的定义。您似乎担心其他应用程序使用该 API;对于任何客户端代码(例如,Web 浏览器中的 javascript),这是不可能完全防止的。 HTTP(S) 请求只是字节;任何代码都可以生成这些字节。默默无闻的安全性可能使攻击者难以确定如何生成这些字节,但它无法阻止此类使用。 【参考方案1】:

如果您想在应用内部使用谷歌地图,您需要为每个请求提供 API 密钥。 Google Maps Android Developer Site 据我所知,这与他们用来识别您的广告应用的机制相同。 该密钥以明文形式传输,因此可以被截取。他们会进行欺诈检测以防止滥用,因此如果您的 RESTful 服务与地图或广告相同,那么这就是适用于 Android 应用程序的方式。

如果您拥有像 snapchat(来自人们的裸体)这样的高价值数据,则用户必须提供一个秘密的又名密码来保护连接。如果您想降低用户的工作量,您可以使用 facebooks 或 googles 身份验证机制。

还可以看看Rest Security Cheat sheet,它会给你一个很好的主题概述。 (尤其是授权部分。)

【讨论】:

根据我的阅读,Snapchat 对第三方应用程序存在/存在问题,对其 API 进行了逆向工程,并能够制作自己的 Snap 应用程序,用户可以登录并使用 API。这是我想阻止的事情。提供用户的秘密或密码是不够的,因为我想限制其他欺骗性的 Android 应用程序使用我的 API。 techcrunch.com/2015/04/03/… android-developers.blogspot.in/2011/03/… 这就是谷歌的想法【参考方案2】:

这是一个相当广泛的主题领域,与 RESTful 服务的实际设计相关,而不是 Android。一般来说,RESTful 服务的设计应该考虑到任何人都可以访问它们,并且您创建安全性以确保您的用户数据是私密的,并且只有有权访问它的人才能访问,因为互联网的现实是一旦端点在那里,人们就可以并且会尝试访问它。

就个人而言,我通常最终使用 JSON Web Tokens (JWT)。您可以在标头中包含一个令牌,该令牌由服务器使用用户提供的凭据进行验证。这允许您验证凭据并拒绝未经授权的访问,因为它基于 OAuth,并且包含一些额外的方法来保护服务,包括令牌到期,因此应用程序必须每 X 分钟/小时/天更新令牌等等,以防有人恶意获取令牌。这也为您提供了一种简单的机制,可以直接从令牌中识别当前用户。 Here's a good introduction to JWTs and what they are composed of.

总之,网络服务的本质是一旦暴露,任何网络连接设备理论上都可以通过欺骗、数据包检查等方式进行连接,而阻止它只让你的应用连接的唯一方法是在设备级别进行身份验证,这需要知道将要连接到服务的每台设备。我认为您需要的是服务级别的强身份验证。良好的 REST API 与平台无关,可在应用程序和网站之间使用,优先考虑的是请求级别的安全性,而不是设备级别的安全。

【讨论】:

按照您描述的方式设置 RESTful API 是正确的。不过,我希望 Android 有某种方法可以真正锁定该 API。但即使是 Snapchat 也有问题。虽然他们禁止,但他们不能阻止某人从他们的私有 API 制作第三方应用程序。结果,第三方应用程序已经开发出来,而 Snapchat 用户只是不了解并使用它们。我正在寻找一种方法来防止 Android 出现这种情况 - 但显然这看起来并不完全可能blog.snapchat.com/post/99998266095/…【参考方案3】:

您可能需要检查one-time password 机制。当您的应用程序安装时,您验证您的用户并为您的应用程序提供一个种子。 每当您的应用程序调用您的 Rest 服务时,您会提供与服务参数一起使用此种子创建的一次性密码。

One time password benefits.

OTP 解决的最重要优势是,在 与静态密码相比,它们不易被重放 攻击。这意味着一个潜在的入侵者设法记录了一个 OTP 已用于登录服务或执行 交易将无法滥用它,因为它不再是 有效。

有一个开放标准HMAC-based One-time Password Algorithm 提供Java 代码供您开始。

【讨论】:

另一种调用这种机制的方式是2-step verification?我说的对吗? 没有。这是不一样的。在两步验证中,您始终使用相同的密码,但另外使用 SMS。在这里,您的密码始终会更改,但由相同的种子创建,因此服务器和客户端会创建相同的新密码并进行验证。 这仍然不会阻止有人对您的 android 应用程序进行逆向工程,获取您拥有的任何 API 逻辑,然后欺骗您的应用程序。 Snapchat 在使用第三方应用程序时遇到了很多问题。我希望有一种独特的方式来识别 my android 应用,但从这些回复看来,其他任何方式都无法实现。 @MicroR 你没有看清楚一次性密码算法。阅读应用程序逻辑和逆向工程是没有用的,因为它已经是一个开放的标准。这就是加密算法的美妙之处,每个人都应该知道它们。 @AtillaOzgur 也许我误解了一些东西,但是使用一次性密码如何防止有人欺骗您的应用程序呢?【参考方案4】:

正如其他人所提到的,发送静态标识符并不能确保您只能从您的应用中获取访问权限。

您需要一种在您的 API 和应用程序之间创建握手的方法,一种简单但非常安全的方法是拥有一个您的应用程序和您的 API 共享的密钥。当您与 API 建立初始连接时,您会创建一个随机字符串,使用共享密钥对其进行加密,并将字符串和加密字符串传递给 API,然后 API 会使用其共享密钥加密您的随机字符串,并将其与您加密的字符串进行比较字符串。

例如:

Random String (RS) (generated by the app) = ABCDEFGHIJKLMNOP
Your shared key (SK) = AAAABBBBCCCCDDDD
Encrypt RS with SK to produce....
Your Encrypted string (ES) = WWWWXXXXYYYYZZZZ

将 RS 和 ES 发送到您的 API,然后使用相同的共享密钥执行相同的加密。如果加密字符串不匹配,API 会拒绝请求并记录 RS,因此无法再次使用 如果匹配,仍会记录 RS,但接受对 API 的访问。您可以在每次使用应用程序时强制重新认证,您也可以在认证成功完成后发送带有任何进一步 API 请求的 RS,但您必须确保在短时间内使 RS 超时。

【讨论】:

如果有人反编译了我的 Android 应用程序,他们不能只查看代码中的共享密钥 (sk) 吗?然后他们只是使用我的应用程序中的任何逻辑来加密 RS,并用它调用 API,不是吗?还是我混淆了什么... 是的,你需要混淆你的代码,即使那样它也不是防弹的,但是,很少有。例如,您可以将 SK 拆分为多个子字符串并使用函数正确重新编译它,在编译应用程序时使用 Proguard 等。在 Android 开发人员网站上有一个很好的解释 Proguard 的使用和好处, developer.android.com/tools/help/proguard.html 是的,这就是我的想法。无论如何,一个坚定的黑客可以通过上述逻辑工作。

以上是关于如何唯一标识您的 Android 应用程序以获取 REST API的主要内容,如果未能解决你的问题,请参考以下文章

如何获取Android唯一标识

如何获取Android唯一标识

如何获取Android唯一标识

如何获取Android唯一标识(唯一序列号)

Swift:如何以编程方式获取iOS设备的唯一标识符?

如何生成唯一的Android设备ID