我正在我们的android应用程序中实现SSL固定。我通过将2个证书(当前证书和备份证书)嵌入到应用程序中来固定了它们。
现在,我想拥有一种机制来更新这些证书,而无需在证书过期或私钥被破坏的情况下不进行应用程序升级。我该如何实施?
我看到的一个可能的解决方案是通过应用程序通知。我可以广播带有新证书的通知,并将其存储在客户端中。这种方法有什么问题还是有更好的方法?
答案 0 :(得分:1)
我正在我们的android应用程序中实现SSL固定。我通过将2个证书(当前证书和备份证书)嵌入到应用程序中来固定了它们。
如果您锁定公钥,则不需要每次在服务器中旋转证书时都更新移动应用,一旦您使用相同的公钥对其进行签名,就可以阅读文章{{3} },了解有关如何完成此操作的更多详细信息:
对于网络连接,Android客户端使用OKHttp库。如果我们的数字证书由Android认可的CA签署,则可以使用默认的信任管理器来验证证书。要固定连接,只需将主机名和证书公钥的哈希添加到客户端builder()。有关示例,请参见此OKHttp配方。具有相同主机名和公共密钥的所有证书都将与哈希匹配,因此可以使用诸如证书轮换之类的技术,而无需客户端更新。多个主机名-公钥元组也可以添加到客户端builder()。
在用于签名证书的私钥遭到破坏的情况下,您最终会遇到与现在尝试解决的情况相同的情况,这就是需要发布新的移动应用程序以更新您信任的内容反对。换句话说,公钥不再受信任,因此服务器必须旋转证书,该证书使用与您随移动应用发布的备份公钥签名的证书。这种方法将为您腾出时间发布新版本,该版本将删除用于签署受感染证书的公钥,而不会锁定所有用户。
您应该始终将备份私钥存储在单独的位置,这样,一旦一个密钥遭到泄露,您就不会一次被所有密钥泄露,因为那样一来,在移动应用中释放备份密码就没有用了。
现在,我想拥有一种机制来更新这些证书,而无需在证书过期或私钥被破坏的情况下不进行应用程序升级。我该如何实施?
不幸的是,处理已泄露私钥的更安全方法是发布一个不再信任它的新移动应用程序。您可能设计的用于更新证书的任何远程解决方案都将为攻击者打开移动应用程序的门,以取代您固定的证书。
所以我的建议是不要走这条路,因为您会比想像的要容易得多。
我看到的一个可能的解决方案是通过应用程序通知。我可以广播带有新证书的通知,并将其存储在客户端中。这种方法有什么问题还是有更好的方法?
虽然移动应用程序固定了连接,但是可以绕开它,因此可以执行MitM攻击,并从攻击者服务器(而不是服务器)中检索新证书。请阅读文章Hands On Mobile APi Security: Pinning Client Connections,以获取有关绕过该文章的更多见解:
取消固定是通过在应用程序运行时对其进行挂钩或拦截来进行的。一旦被拦截,钩子框架就可以更改传入或传出函数的值。当您使用HTTP库实现固定时,该库调用的功能是众所周知的,因此人们编写了专门钩挂这些检查功能的模块,因此无论TLS握手中使用的实际证书如何,它们始终可以通过。 iOS也有类似的方法。
仍然强烈建议您使用可绕过证书固定的方式,因为安全性完全取决于防御层,越多的人越会克服所有这些困难……这并不是什么新鲜事,如果您想起中世纪的城堡,就是用这种方法建造的。
但是您还要求一种更好的方法:
此方法是否存在问题或有更好的方法?
如上所述,您应该固定证书的公钥,以避免在旋转服务器证书时客户端被锁定。
虽然我无法为您指出一种更好的方法来处理遭到破坏的私钥,但我可以指出,为了防止证书锁定被诸如xPosed或Frida之类的内省框架所绕过,我们可以采用移动应用证明技术,证明移动应用程序的真实性。
将您自己的脚本注入黑盒进程。挂钩任何功能,监视加密API或跟踪私有应用程序代码,不需要任何源代码。编辑,点击保存,立即查看结果。全部没有编译步骤或程序重新启动。
Xposed是用于模块的框架,可以在不触摸任何APK的情况下更改系统和应用程序的行为。太好了,因为这意味着模块可以用于不同版本甚至ROM,而无需进行任何更改(只要原始代码的更改不太多)。撤消操作也很容易。
在我们深入研究移动应用证明技术之前,我想先澄清一下开发人员中常见的关于 WHO 和 What 正在调用API服务器的误解
为了更好地了解 WHO 和 What 在访问API服务器之间的区别,让我们使用以下图片:
预期的通信渠道表示合法用户没有任何恶意意图就可以使用您期望的移动应用程序,它使用的是未修改版本的移动应用程序,并且可以直接与API服务器通信,而不会受到中间人的攻击。
实际渠道可能代表几种不同的情况,例如具有恶意意图的合法用户可能正在使用移动应用程序的重新打包版本,黑客使用了移动应用程序的真实版本,而中间人则在进行攻击,了解移动应用程序与API服务器之间的通信是如何进行的,以便能够自动对您的API进行攻击。可能还有许多其他情况,但是我们在这里不逐一列举。
我希望到现在为止您可能已经知道为什么 WHO 和 What 不同的地方,但是如果不一样的话,一会儿就会明白。
WHO 是我们可以通过多种方式(例如使用OpenID Connect或OAUTH2流)进行身份验证,授权和标识的移动应用程序的用户。
通常,OAuth代表资源所有者向客户端提供对服务器资源的“安全委派访问”。它为资源所有者指定了一个在不共享凭据的情况下授权第三方访问其服务器资源的过程。 OAuth专为与超文本传输协议(HTTP)配合使用而设计,实质上允许在资源所有者的批准下,授权服务器将访问令牌发布给第三方客户端。然后,第三方使用访问令牌访问资源服务器托管的受保护资源。
OpenID Connect 1.0是OAuth 2.0协议之上的简单身份层。它允许客户端根据授权服务器执行的身份验证来验证最终用户的身份,并以可互操作且类似于REST的方式获取有关最终用户的基本配置文件信息。
尽管用户身份验证可能会让API服务器知道 WHO 正在使用API,但不能保证请求源自您期望的 What 。移动应用。
现在,我们需要一种方法来识别正在调用的API服务器,这使得事情变得比大多数开发人员想象的要棘手。 内容是向API服务器发出请求的内容。它是移动应用程序的真正实例,还是使用诸如Postman之类的工具通过API服务器手动访问的机器人,自动脚本或攻击者?
让您感到惊讶的是,您可能最终发现它可能是使用重新打包的移动应用程序版本或试图游戏化并利用该应用程序提供的服务的自动脚本的合法用户之一。
以上文章摘录自我写的一篇文章,题为《 为什么您的移动应用程序需要API密钥?”,因此您可以完整阅读OpenID Connect,即有关API密钥的系列文章中的第一篇。
使用移动应用证明解决方案将使API服务器能够知道正在发送请求的内容,从而仅响应来自真正移动应用的请求,而拒绝来自不安全来源的所有其他请求。
移动应用程序证明服务的作用是在运行时通过在后台运行将与云中运行的服务进行通信的SDK来确保您的移动应用程序未被篡改或未在有根设备中运行证明移动应用程序和设备正在运行的完整性。
在成功证明移动应用程序完整性之后,将发布并使用一个秘密的短期生存JWT令牌进行签名,该秘密只有云中的API服务器和移动应用程序证明服务可以识别。如果移动应用程序证明失败,则会使用API服务器不知道的秘密对JWT令牌进行签名。
现在,应用程序必须随每个API一起发送,并在请求的标头中调用JWT令牌。这将允许API服务器仅在可以验证JWT令牌中的签名和到期时间时才处理请求,而在验证失败时拒绝它们。
一旦移动应用程序不知道移动应用程序证明服务使用的机密,即使在应用程序被篡改,在有根设备上运行或通过连接进行通信时,也无法在运行时对其进行反向工程成为中间攻击中一名男子的目标。
因此,该解决方案可在没有误报的积极检测模型中工作,从而不会阻止合法用户,同时又将坏人拒之门外。
移动应用程序认证服务已经作为here上的SAAS解决方案存在(我在这里工作),该服务提供了多个平台的SDK,包括iOS,Android,React Native等。集成还需要在API服务器代码中进行少量检查,以验证由云服务发出的JWT令牌。对于API服务器来说,必须进行此检查才能决定要处理的请求和拒绝的请求。
因此,我建议您切换为使用公钥固定证书,并且如果要防止绕过证书固定和其他威胁,则应设计自己的移动应用程序证明解决方案或使用已准备好的解决方案即插即用。
因此,最后,必须根据要保护的内容的值以及该类型数据的法律要求(例如GDPR)来选择用于保护您的Mobile APP和API服务器的解决方案欧洲法规。
OWASP移动安全项目是一个集中式资源,旨在为开发人员和安全团队提供构建和维护安全移动应用程序所需的资源。通过该项目,我们的目标是对移动安全风险进行分类并提供开发控制措施,以减少其影响或被利用的可能性。