流行的应用程序如何验证用户请求从他们的移动应用程序到服务器?


118

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

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

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

抱歉,如果这不是一些公共信息。

Answers:


48

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

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

如果您从Android框架中连接到同步适配器,则可以在后台进行同步和身份验证。

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

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


19

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

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

回到答案,正如彼得潘所说,基于令牌的身份验证方式是一次性的,而且不合时宜。这些令牌已过期或在某些情况下将权力授予开发人员。

有趣的是,可以定义资源访问范围,而不是允许客户端应用程序保留危险的用户名和密码。

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

在此处输入图片说明

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


13

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

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

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

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

中间人攻击

预期的通信渠道表示合法用户在没有任何恶意意图的情况下正按预期使用该移动应用程序,使用该移动应用程序的未修改版本,并直接与API服务器通信,而不会受到中间人的攻击。

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

我希望到现在为止您可能已经有了线索,为什么WHOWHAT并不相同,但是如果不是这样的话,那一会儿就会明白。

世界卫生组织是移动应用程序,我们可以验证,授权和以多种方式确定,比如使用OpenID登录连接或流的oauth2的用户。

绿洲

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

OpenID连接

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

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

现在,我们需要一种方法来确定什么是调用API服务器,这里的事情变得比大多数开发人员可能会觉得更靠谱。在什么是发出请求到服务器API的东西。它确实是移动应用程序的真正实例,还是使用诸如Postman之类的工具通过API服务器手动访问的机器人,自动脚本或攻击者?

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

好吧,为了确定WHAT,开发人员倾向于使用通常在其移动应用程序代码中进行硬编码的API密钥。一些开发人员付出了更多的努力,并在移动应用程序中在运行时计算了密钥,因此与将静态机密嵌入代码中的前一种方法相反,它成为了运行时机密。

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

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

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

您保存在设备中的任何内容(即使已加密)也可以在运行时使用Frida或Xposed等工具进行反向工程。

弗里达

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

x位置

Xposed是一个模块框架,可以在不触摸任何APK的情况下更改系统和应用程序的行为。太好了,因为这意味着模块可以在不做任何更改的情况下适用于不同版本甚至ROM(只要原始代码

在设备中,攻击者控制着攻击者还可以使用代理来执行“中间人攻击”,以提取您可以用来识别WHATWHO的任何秘密,正如我在文章“ 窃取攻击者的API密钥”中所显示的那样

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

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

可能的解决方案

有人可以告诉我著名的android应用程序(例如Facebook,FourSquare或Twitter)使用什么方法来验证从移动应用程序到服务器的每个请求吗?

抱歉,但是我对此应用程序的了解不足,无法阐明您的观点,但是我可以为您指出其他一些方法。

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

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

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

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

行动应用程式证明

使用移动应用程序认证解决方案将使API服务器就知道什么是发送请求,因此允许而拒绝来自不安全来源的所有其他请求从一个真正的移动应用程序只响应请求。

移动应用程序证明解决方案的作用是在运行时保证您的移动应用程序未被篡改,不在有根设备上运行,没有被xPosed或Frida之类的框架检测,未被MitM攻击,并且通过在后台运行SDK来实现。在云中运行的服务将对应用程序构成挑战,并基于响应将证明移动应用程序和设备所运行的完整性,因此SDK绝不负责任何决定。

在成功证明移动应用程序完整性之后,将发布并签名一个短时生存的JWT令牌,并秘密告知只有云服务器中的API服务器和移动应用程序证明服务。在移动应用证明失败的情况下,将使用API​​服务器不知道的秘密对JWT令牌进行签名。

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

一旦移动应用程序不知道移动应用程序证明服务使用的机密,就无法在运行时对其进行反向工程,即使该应用程序被篡改,在有根设备中运行或通过正在作为连接的连接进行通信中间攻击中一名男子的目标。

移动应用证明服务已经作为Approov的SAAS解决方案存在(我在这里工作),该服务提供了多个平台的SDK,包括iOS,Android,React Native等。集成还需要在API服务器代码中进行少量检查,以验证由云服务发出的JWT令牌。API服务器必须能够执行此检查,才能决定服务哪些请求以及拒绝哪些请求。

结论

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

您想走额外的里程吗?

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

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



3

我是新手,但我将尝试为给定的问题提供合理的解决方案。

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

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

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


3

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


-7

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


您可以使用SharedPreferences,但默认情况下未加密您的数据。如果你担心的是,看到如在SO讨论:stackoverflow.com/questions/785973/...
迈克尔Helwig

3
SharedPreferences不是存储凭据的安全位置。任何有根设备(不难做到)将公开这些凭据。而是使用内置帐户API。
Brill Pappin

SharedPreferences也可以从无根设备下载,如果我没记错的话,可以通过Android系统的备份机制下载。有多种工具可从Android备份文件中提取可读文件。
Darthmail

@BrillPappin有关您的评论的问题。存储的凭据是用户的电子邮件和密码,以及要发送的令牌,该令牌代表该电子邮件的当前身份验证。如果用户选择通过生根向自己公开自己的凭据,那会有什么风险?
ToolmakerSteve

风险是双重的。1)您必须假定的任何容易访问的敏感数据都将被访问。您可能并不在乎,但其他人可能会。2)密码短语的任何存储都不安全。
Brill Pappin
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.