如何确保我的 iOS 应用程序的完整性?
How can I ensure the integrity of my iOS app?
我要求必须检查我的 Swift iOS 应用程序的签名。
我认为它只与越狱设备有关,因为 iOS 会自行检查完整性。
我在网上找不到太多内容 - 大多数 libraries/snippets 已经 5 年没有更新了。
我目前的方法是计算应用程序签名(C 代码)并将其与从服务器加载的签名数组进行比较。一个数组,因为支持多个版本的应用程序。
对这种方法有什么想法或意见吗?也许它不再与 Swift 相关?
这里有一些资源可以激发我的解决方案:
您当前的方法
My current approach would be to calculate the app signature (C-Code) and compare it with an array of signatures that have been loaded from the server.
我需要提醒您一个事实,即在获得 root 权限的 phone 中,攻击者将能够在 run-time 拦截您的代码并修改其行为,这意味着您检测签名没问题总是returntrue
。他们通过使用像 Frida:
这样的内省框架来做到这一点
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
您的要求
I have the requirement that the signature of my Swift iOS app has to be checked. I think it is only relevant for jailbroken devices as iOS checks the integrity by itself.
好吧,如果此要求的目的只是为了保护您的应用程序免受 root 设备中 运行 的影响,检查应用程序的签名是不够的,一旦设备被 root,它上面的任何应用程序都可以容易操纵,正如我已经提到的。保护应用程序免受设备本身的攻击是一项艰巨的任务,就像与攻击者玩猫捉老鼠的游戏一样,要在游戏中保持领先。您将需要在应用程序保护中使用来检测应用程序是否在 jail-broken 设备中 运行,是否附加了内省框架,是否在模拟器中 运行,是否附加了调试器,等等。这是与攻击者的一场永无止境的游戏,他们拥有巨大的优势,他们可以投入所有的资源和时间来破坏你的应用程序,如果这对他们来说是值得的,但你可能没有相同的人力资源、时间和投资这个游戏的钱。无论您决定如何玩游戏,您始终可以求助于 Apple Device Check API 在 API 服务器中标记特定设备不可信。
如果检查 iOS 应用程序签名的要求更符合保护 API 服务器不接收来自 iOS 非正版应用程序的请求,您已经上传到Apple store,那么可能会有更好的解决方案,并且被称为Mobile APP Attestation。所以如果这也在你的要求范围内,你应该继续阅读,否则就跳过它。
在深入探讨移动应用程序证明概念之前,我想首先澄清一个关于 WHO 和 WHAT 正在访问 API服务器。
访问 API 服务器的 WHO 和 WHAT 之间的区别
为了更好地理解 WHO 和 WHAT 访问 API 服务器之间的区别,让我们使用这张图片:
所以把移动应用换成网络应用,继续按照我对这张图的类比。
预期的通信渠道表示 Web 应用程序正按您的预期使用,由合法用户没有任何恶意,从浏览器与 API 服务器通信,不使用 Postman 或使用任何其他工具来执行中间人 (MitM) 攻击。
实际的渠道可能代表几种不同的场景,比如一个怀有恶意的合法用户可能正在使用 Curl 或 Postman 等工具来执行请求,黑客使用 MitM 攻击工具(如 MitmProxy)来了解如何Web 应用程序和 API 服务器之间的通信正在完成,以便能够重播请求甚至自动攻击 API 服务器。还有很多其他可能的情况,但我们不会在这里一一列举。
我希望现在您可能已经知道为什么 WHO 和 WHAT 不一样,但如果不一样一会儿就清楚了。
WHO 是 Web 应用程序的用户,我们可以通过多种方式对其进行身份验证、授权和识别,例如使用 OpenID Connect 或 OAUTH2 流程。
Generally, OAuth provides to clients a "secure delegated access" to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
虽然用户身份验证可以让 API 服务器知道 WHO 在使用 API,但不能保证请求来自 你期望什么,你的网络应用程序的浏览器应该是 运行 来自真实用户的。
现在我们需要一种方法来识别什么 正在调用API 服务器,这里事情变得比大多数开发人员想象的更棘手。 WHAT 是向 API 服务器发出请求的东西。它真的是 Web 应用程序的真实实例,还是机器人、自动脚本或攻击者使用 Postman 等工具手动浏览 API 服务器?
令您惊讶的是,您最终可能会发现它可能是手动操作请求的合法用户之一,或者是试图游戏化并利用网络应用程序提供的服务的自动化脚本。
嗯,为了识别 WHAT,开发人员倾向于求助于通常在 Web 应用程序的 headers 中发送的 API 密钥。一些开发人员更加努力地计算 Web 应用程序中 run-time 处的密钥,在混淆后的 javascript 中,因此它成为一个运行时秘密,可以通过反总线工具进行逆向工程,并通过检查流量使用 F12 或 MitM 工具在 Web 应用程序和 API 服务器之间。
以上write-up摘自我写的一篇文章,标题为为什么你的手机应用程序需要一个API 密钥?。虽然在移动应用程序的上下文中,但总体思想在网络应用程序的上下文中仍然有效。希望您能完整阅读这篇文章 here,这是关于 API 键的系列文章中的第一篇。
移动应用认证
移动应用证明解决方案的使用将使 API 服务器知道 WHAT 正在发送请求,从而允许仅响应来自真实应用程序的请求移动应用程序,同时拒绝来自不安全来源的所有其他请求。
移动应用证明解决方案的作用是在 run-time 保证您的移动应用未被篡改,未 运行 在已获得 root 权限的设备中,未被类似框架检测Frida,没有被 MitM 攻击,这是通过后台的 运行 SDK 实现的。云中的服务 运行 将挑战应用程序,并根据响应证明移动应用程序和设备的完整性是 运行,因此 SDK 永远不会对任何决定负责。
An interactive TLS-capable intercepting HTTP proxy for penetration testers and software developers.
在成功证明移动应用程序完整性后,将发布一个短期 JWT 令牌并使用只有 API 服务器和云中的移动应用程序证明服务知道的秘密进行签名。如果移动应用程序证明失败,JWT 令牌将使用 API 服务器不知道的秘密进行签名。
现在,应用程序必须在每次 API 调用请求的 headers 中发送 JWT 令牌。这将允许 API 服务器仅在可以验证 JWT 令牌中的签名和过期时间时才为请求提供服务,并在验证失败时拒绝请求。
一旦移动应用程序不知道移动应用程序证明服务使用的秘密,即使应用程序被篡改,也无法在 run-time 对其进行逆向工程,运行 root 设备或通过成为中间人攻击目标的连接进行通信。
Approov(我在这里工作)的移动应用证明服务已经作为 SAAS 解决方案存在,它为多个平台提供 SDK,包括 iOS、Android、React Native 等。集成还需要在 API 服务器代码中进行少量检查,以验证云服务发布的 JWT 令牌。此检查对于 API 服务器来说是必要的,以便能够决定处理哪些请求以及拒绝哪些请求。
总结
最后,为了保护您的 API 服务器而使用的解决方案必须根据您要保护的内容的价值以及该类型数据的法律要求来选择,例如欧洲的 GDPR 法规。
加倍努力
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.
我要求必须检查我的 Swift iOS 应用程序的签名。 我认为它只与越狱设备有关,因为 iOS 会自行检查完整性。
我在网上找不到太多内容 - 大多数 libraries/snippets 已经 5 年没有更新了。 我目前的方法是计算应用程序签名(C 代码)并将其与从服务器加载的签名数组进行比较。一个数组,因为支持多个版本的应用程序。
对这种方法有什么想法或意见吗?也许它不再与 Swift 相关?
这里有一些资源可以激发我的解决方案:
您当前的方法
My current approach would be to calculate the app signature (C-Code) and compare it with an array of signatures that have been loaded from the server.
我需要提醒您一个事实,即在获得 root 权限的 phone 中,攻击者将能够在 run-time 拦截您的代码并修改其行为,这意味着您检测签名没问题总是returntrue
。他们通过使用像 Frida:
Inject your own scripts into black box processes. Hook any function, spy on crypto APIs or trace private application code, no source code needed. Edit, hit save, and instantly see the results. All without compilation steps or program restarts.
您的要求
I have the requirement that the signature of my Swift iOS app has to be checked. I think it is only relevant for jailbroken devices as iOS checks the integrity by itself.
好吧,如果此要求的目的只是为了保护您的应用程序免受 root 设备中 运行 的影响,检查应用程序的签名是不够的,一旦设备被 root,它上面的任何应用程序都可以容易操纵,正如我已经提到的。保护应用程序免受设备本身的攻击是一项艰巨的任务,就像与攻击者玩猫捉老鼠的游戏一样,要在游戏中保持领先。您将需要在应用程序保护中使用来检测应用程序是否在 jail-broken 设备中 运行,是否附加了内省框架,是否在模拟器中 运行,是否附加了调试器,等等。这是与攻击者的一场永无止境的游戏,他们拥有巨大的优势,他们可以投入所有的资源和时间来破坏你的应用程序,如果这对他们来说是值得的,但你可能没有相同的人力资源、时间和投资这个游戏的钱。无论您决定如何玩游戏,您始终可以求助于 Apple Device Check API 在 API 服务器中标记特定设备不可信。
如果检查 iOS 应用程序签名的要求更符合保护 API 服务器不接收来自 iOS 非正版应用程序的请求,您已经上传到Apple store,那么可能会有更好的解决方案,并且被称为Mobile APP Attestation。所以如果这也在你的要求范围内,你应该继续阅读,否则就跳过它。
在深入探讨移动应用程序证明概念之前,我想首先澄清一个关于 WHO 和 WHAT 正在访问 API服务器。
访问 API 服务器的 WHO 和 WHAT 之间的区别
为了更好地理解 WHO 和 WHAT 访问 API 服务器之间的区别,让我们使用这张图片:
所以把移动应用换成网络应用,继续按照我对这张图的类比。
预期的通信渠道表示 Web 应用程序正按您的预期使用,由合法用户没有任何恶意,从浏览器与 API 服务器通信,不使用 Postman 或使用任何其他工具来执行中间人 (MitM) 攻击。
实际的渠道可能代表几种不同的场景,比如一个怀有恶意的合法用户可能正在使用 Curl 或 Postman 等工具来执行请求,黑客使用 MitM 攻击工具(如 MitmProxy)来了解如何Web 应用程序和 API 服务器之间的通信正在完成,以便能够重播请求甚至自动攻击 API 服务器。还有很多其他可能的情况,但我们不会在这里一一列举。
我希望现在您可能已经知道为什么 WHO 和 WHAT 不一样,但如果不一样一会儿就清楚了。
WHO 是 Web 应用程序的用户,我们可以通过多种方式对其进行身份验证、授权和识别,例如使用 OpenID Connect 或 OAUTH2 流程。
Generally, OAuth provides to clients a "secure delegated access" to server resources on behalf of a resource owner. It specifies a process for resource owners to authorize third-party access to their server resources without sharing their credentials. Designed specifically to work with Hypertext Transfer Protocol (HTTP), OAuth essentially allows access tokens to be issued to third-party clients by an authorization server, with the approval of the resource owner. The third party then uses the access token to access the protected resources hosted by the resource server.
OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It allows Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner.
虽然用户身份验证可以让 API 服务器知道 WHO 在使用 API,但不能保证请求来自 你期望什么,你的网络应用程序的浏览器应该是 运行 来自真实用户的。
现在我们需要一种方法来识别什么 正在调用API 服务器,这里事情变得比大多数开发人员想象的更棘手。 WHAT 是向 API 服务器发出请求的东西。它真的是 Web 应用程序的真实实例,还是机器人、自动脚本或攻击者使用 Postman 等工具手动浏览 API 服务器?
令您惊讶的是,您最终可能会发现它可能是手动操作请求的合法用户之一,或者是试图游戏化并利用网络应用程序提供的服务的自动化脚本。
嗯,为了识别 WHAT,开发人员倾向于求助于通常在 Web 应用程序的 headers 中发送的 API 密钥。一些开发人员更加努力地计算 Web 应用程序中 run-time 处的密钥,在混淆后的 javascript 中,因此它成为一个运行时秘密,可以通过反总线工具进行逆向工程,并通过检查流量使用 F12 或 MitM 工具在 Web 应用程序和 API 服务器之间。
以上write-up摘自我写的一篇文章,标题为为什么你的手机应用程序需要一个API 密钥?。虽然在移动应用程序的上下文中,但总体思想在网络应用程序的上下文中仍然有效。希望您能完整阅读这篇文章 here,这是关于 API 键的系列文章中的第一篇。
移动应用认证
移动应用证明解决方案的使用将使 API 服务器知道 WHAT 正在发送请求,从而允许仅响应来自真实应用程序的请求移动应用程序,同时拒绝来自不安全来源的所有其他请求。
移动应用证明解决方案的作用是在 run-time 保证您的移动应用未被篡改,未 运行 在已获得 root 权限的设备中,未被类似框架检测Frida,没有被 MitM 攻击,这是通过后台的 运行 SDK 实现的。云中的服务 运行 将挑战应用程序,并根据响应证明移动应用程序和设备的完整性是 运行,因此 SDK 永远不会对任何决定负责。
An interactive TLS-capable intercepting HTTP proxy for penetration testers and software developers.
在成功证明移动应用程序完整性后,将发布一个短期 JWT 令牌并使用只有 API 服务器和云中的移动应用程序证明服务知道的秘密进行签名。如果移动应用程序证明失败,JWT 令牌将使用 API 服务器不知道的秘密进行签名。
现在,应用程序必须在每次 API 调用请求的 headers 中发送 JWT 令牌。这将允许 API 服务器仅在可以验证 JWT 令牌中的签名和过期时间时才为请求提供服务,并在验证失败时拒绝请求。
一旦移动应用程序不知道移动应用程序证明服务使用的秘密,即使应用程序被篡改,也无法在 run-time 对其进行逆向工程,运行 root 设备或通过成为中间人攻击目标的连接进行通信。
Approov(我在这里工作)的移动应用证明服务已经作为 SAAS 解决方案存在,它为多个平台提供 SDK,包括 iOS、Android、React Native 等。集成还需要在 API 服务器代码中进行少量检查,以验证云服务发布的 JWT 令牌。此检查对于 API 服务器来说是必要的,以便能够决定处理哪些请求以及拒绝哪些请求。
总结
最后,为了保护您的 API 服务器而使用的解决方案必须根据您要保护的内容的价值以及该类型数据的法律要求来选择,例如欧洲的 GDPR 法规。
加倍努力
OWASP Mobile Security Project - Top 10 risks
The OWASP Mobile Security Project is a centralized resource intended to give developers and security teams the resources they need to build and maintain secure mobile applications. Through the project, our goal is to classify mobile security risks and provide developmental controls to reduce their impact or likelihood of exploitation.