135

假设我有一个连接到 .Net API 以接收/设置数据的 Android 应用程序。我的困惑是关于如何第一次注册/登录用户并在他们每次向 API 发出请求时对其进行身份验证。

  • 如果我只使用基于用户名/密码的身份验证,它们会不够安全吗?
  • 而且出于安全原因,我无法将该用户名/密码保存在设备中?
  • 我是否应该在注册时为每个用户颁发一个 GUID,将其保存在他们的设备中并在每次 API 请求期间检索?

还有哪些其他模式可用,哪些最有效和最安全,我只需要一个流程即可。有人能告诉我 Facebook、FourSquare 或 Twitter 等著名的 android 应用程序使用什么方法来验证从他们的移动应用程序到他们的服务器的每个请求吗?

如果这不是一些公共信息,请提前道歉。

4

7 回答 7

55

我想他们使用基于“令牌”的安全系统,因此密码实际上从未存储在任何地方,只是第一次用于身份验证。因此,应用程序最初发布用户名/密码(通过 ssl),服务器返回应用程序存储的令牌。对于随后的同步尝试,首先发送令牌,服务器检查它是否有效,然后允许发布其他数据。

令牌应该有一个有效期,以便服务器可以重新请求身份验证尝试。

如果您从 Android 框架中连接到同步适配器,这将使您能够在后台同步和验证所有内容。

http://developer.android.com/training/sync-adapter/creating-sync-adapter.html

如果您检查设备上“设置”下的帐户,您就会明白我的意思。

于 2013-11-05T21:44:34.263 回答
24

如果我只使用基于用户名/密码的身份验证,它们会不够安全吗?

不,因为您只是在识别WHO正在访问 API 服务器,而不是WHAT正在访问它。

访问 API 服务器的 WHO 和 WHAT 之间的区别

为了更好地理解WHOWHAT访问 API 服务器之间的区别,让我们使用这张图片:

中间人攻击

Intended Communication Channel 表示移动应用程序正按您的预期被合法用户使用,没有任何恶意,使用未经篡改的移动应用程序版本,并直接与 API 服务器通信而不会受到中间人的攻击。

实际渠道可能代表几种不同的场景,例如怀有恶意的合法用户可能正在使用重新打包的移动应用程序版本,黑客使用移动应用程序的正版版本,而中间人攻击它,以了解如何移动应用程序和 API 服务器之间的通信正在完成,以便能够自动攻击您的 API。许多其他情况也是可能的,但我们不会在这里一一列举。

我希望现在你可能已经知道为什么WHOWHAT不一样,但如果不是,一会儿就会清楚。

WHO是移动应用程序的用户,我们可以通过多种方式对其进行身份验证、授权和识别,例如使用 OpenID Connect 或 OAUTH2 流。

认证

通常,OAuth 代表资源所有者向客户端提供对服务器资源的“安全委托访问”。它指定了资源所有者授权第三方访问其服务器资源而不共享其凭据的过程。OAuth 专为与超文本传输​​协议 (HTTP) 一起使用而设计,本质上允许授权服务器在资源所有者的批准下将访问令牌颁发给第三方客户端。然后第三方使用访问令牌访问资源服务器托管的受保护资源。

OpenID 连接

OpenID Connect 1.0 是 OAuth 2.0 协议之上的简单身份层。它允许客户端根据授权服务器执行的身份验证验证最终用户的身份,并以可互操作和类似 REST 的方式获取有关最终​​用户的基本配置文件信息。

虽然用户身份验证可以让 API 服务器知道在使用 API,但它不能保证请求来自所期望的,即移动应用程序的原始版本。

现在我们需要一种方法来识别是什么在调用 API 服务器,而这里的事情变得比大多数开发人员想象的要复杂得多。什么是向 API 服务器发出请求的东西。它真的是移动应用程序的真实实例,还是机器人、自动脚本或攻击者使用 Postman 之类的工具手动探索 API 服务器?

令您惊讶的是,您最终可能会发现它可能是使用重新打包的移动应用程序版本或试图游戏化并利用应用程序提供的服务的自动化脚本的合法用户之一。

好吧,为了识别WHAT,开发人员倾向于求助于 API 密钥,通常他们将其硬编码在他们的移动应用程序的代码中。一些开发人员加倍努力并在运行时在移动应用程序中计算密钥,因此它成为运行时机密,而不是前一种方法,即在代码中嵌入静态机密。

上面的文章摘自我写的一篇文章,题为为什么您的移动应用程序需要 API 密钥?,您可以在此处完整阅读,这是有关 API 密钥的系列文章中的第一篇。

在客户端设备中存储敏感数据

而且出于安全原因,我无法将该用户名/密码保存在设备中?我是否应该在注册时为每个用户颁发一个 GUID,将其保存在他们的设备中并在每次 API 请求期间检索?

您保存在设备中的任何内容,即使是加密的,都可以在运行时使用 Frida 或 Xposed 等工具进行逆向工程。

弗里达

将您自己的脚本注入黑盒进程。挂钩任何功能、监视加密 API 或跟踪私有应用程序代码,无需源代码。编辑,点击保存,立即查看结果。所有这些都无需编译步骤或程序重新启动。

摆姿势

Xposed 是一个模块框架,可以在不触及任何 APK 的情况下改变系统和应用程序的行为。这很棒,因为这意味着模块可以在不同版本甚至 ROM 上工作而无需任何更改(只要原始代码

在攻击者控制的设备中,他还可以使用代理来执行中间人攻击,以提取您可能用来识别WHATWHO的任何秘密,正如我在文章Steal that API Key with a Man in the Attack 中所展示的那样:

虽然我们可以使用 JNI/NDK 等高级技术将 API 密钥隐藏在移动应用程序代码中,但它不会阻止某人执行中间人攻击以窃取 API 密钥。事实上,中间人攻击很容易,甚至可以由非开发人员实现。

那么现在什么...我注定无法保护我的 API 服务器不被滥用???没有安静所以......希望仍然存在!

可能的解决方案

有人能告诉我 Facebook、FourSquare 或 Twitter 等著名的 android 应用程序使用什么方法来验证从他们的移动应用程序到他们的服务器的每个请求吗?

抱歉,我没有足够的知识来解释你的这个应用程序,但我可以为你指出一些其他的方法。

还有哪些其他模式可用,哪些最有效和最安全,我只需要一个流程即可。

因此,在客户端运行并需要一些秘密来访问 API 的任何东西都可能以不同的方式被滥用,您可以在本系列关于移动 API 安全技术的文章中了解更多信息。本文将教您如何使用 API 密钥、用户访问令牌、HMAC 和 TLS 固定来保护 API,以及如何绕过它们。

要解决什么是访问您的移动应用程序的问题,您需要使用我上面提到的关于移动 API 安全技术的系列文章中提到的一个或所有解决方案,并接受它们只能使未经授权的访问您的 API 服务器更难绕过但并非不可能。

通过使用移动应用程序证明解决方案可以采用更好的解决方案,该解决方案将使 API 服务器知道只接收来自真正移动应用程序的请求。

移动应用证明

使用移动应用程序证明解决方案将使 API 服务器能够了解发送请求的内容,从而允许仅响应来自真正移动应用程序的请求,同时拒绝来自不安全来源的所有其他请求。

移动应用程序证明解决方案的作用是在运行时保证您的移动应用程序没有被篡改,没有在有根设备中运行,没有被 xPosed 或 Frida 等框架检测,没有受到中间人攻击,而且是通过在后台运行 SDK 来实现的。在云中运行的服务将挑战应用程序,并根据响应证明移动应用程序和设备正在运行的完整性,因此 SDK 永远不会对任何决定负责。

在成功证明移动应用程序完整性后,将发布一个短期 JWT 令牌并使用只有云中的 API 服务器和移动应用程序证明服务知道的秘密进行签名。如果移动应用程序证明失败,JWT 令牌会使用 API 服务器不知道的秘密进行签名。

现在,应用程序必须在每个 API 调用中发送请求标头中的 JWT 令牌。这将允许 API 服务器仅在可以验证 JWT 令牌中的签名和过期时间时服务请求,并在验证失败时拒绝它们。

一旦移动应用程序不知道移动应用程序证明服务所使用的秘密,即使应用程序被篡改、在有根设备中运行或通过正在运行的连接进行通信,也不可能在运行时对其进行反向工程。中间人攻击的目标。

移动应用证明服务已经作为 Approov(我在这里工作)的 SAAS 解决方案存在,它为多个平台提供 SDK,包括 iOS、Android、React Native 等。集成还需要对 API 服务器代码进行小检查,以验证云服务发布的 JWT 令牌。此检查对于 API 服务器能够决定服务哪些请求和拒绝哪些请求是必要的。

结论

最后,必须根据您要保护的内容的价值以及该类型数据的法律要求(例如欧洲的 GDPR 法规)来选择用于保护您的 API 服务器的解决方案。

你想加倍努力吗?

OWASP 移动安全项目 - 十大风险

OWASP 移动安全项目是一个集中资源,旨在为开发人员和安全团队提供构建和维护安全移动应用程序所需的资源。通过该项目,我们的目标是对移动安全风险进行分类并提供开发控制以减少其影响或被利用的可能性。

于 2019-08-29T13:45:51.683 回答
23

基本上这些著名的使用 OAuth 协议(1)/框架(2)。尽管它必须是一个标准,但它们中的每一个都有这个协议/框架的不同实现。因此,在集成方面我们必须非常小心。

示例:Dropbox 仍然使用 OAuth 1,并且最近提出了 OAuth 2 支持。

回到答案,正如 peterpan 所说,它是一种基于令牌的身份验证方式,它是一次性的,并且超出了等式。这些令牌已过期,或者在某些情况下赋予开发人员权力。

这背后的有趣之处在于,可以定义资源访问范围,而不是允许客户端应用程序保留用户名、密码,这是危险的。

这是其工作原理的基本说明。

在此处输入图像描述

在获得更多详细信息后,我将更新答案,因为这些天我在这个领域工作:)

于 2014-12-23T20:14:33.630 回答
3

我正在寻找完全相同的东西并找到了谷歌的方式,就像彼得潘所说的那样,但是通过谷歌 API。试试这个链接,用谷歌搜索,我也开始了!我会在我在它的时候发布新信息!

http://developer.android.com/google/auth/http-auth.html

于 2015-01-15T12:40:20.520 回答
3

我是新手,但我会尝试为给定的问题提供合乎逻辑的解决方案。

将有两个选项,[1] 对于每个 URI,将执行 http 身份验证,其中将验证用户输入的凭据并且用户将访问资源。

[2] 另一种方法可能是,用户应进行身份验证,并且在每次身份验证时都会生成一个唯一的令牌。使用生成的令牌,用户可以访问资源。

虽然我不确定哪种方法最适合移动应用程序。

于 2015-07-31T13:03:13.370 回答
3

身份验证示例是一个很好的起点。Android 将凭据存储在帐户管理器中,您可以在 Android 的设置中查看帐户。这将自动存储令牌,如果过期或丢失提示用户输入凭据,刷新令牌等。我发现此示例的 http 部分缺少或旧。扩展android的AccountAuthenticatorActivity是一个很好的帮手,可以将序列化的数据解析到layout并返回到internet。

于 2016-02-17T02:23:05.630 回答
-9

放置在SharedPreferences中时,用户名和密码可以是安全的。 使用 https 连接到服务器也应该足够好。

于 2013-11-05T21:43:21.397 回答