如何更新固定的 ssl 证书 android

cto*_*tor 5 ssl android certificate-pinning public-key-pinning

我正在我们的 android 应用程序中实现 SSL 固定。我通过将 2 个证书(当前和备份)嵌入到应用程序中来将它们固定在客户端。

现在,我希望有一种机制来更新这些证书,而无需推出应用程序升级,以防证书过期或私钥被泄露。我该如何实施?

我看到的一种可能的解决方案是通过应用程序通知。我可以使用新证书广播通知并将它们存储在客户端中。这种方法有什么问题还是有更好的方法?

Exa*_*a37 13

公钥锁定

我正在我们的 android 应用程序中实现 SSL 固定。我通过将 2 个证书(当前和备份)嵌入到应用程序中来将它们固定在客户端。

如果您锁定公钥,则无需在每次在服务器中轮换证书时更新您的移动应用程序,一旦您使用相同的公钥对其进行签名,您就可以阅读文章Hands On Mobile APi Security: Pinning客户端连接以获取有关如何完成此操作的更多详细信息:

对于联网,Android 客户端使用 OKHttp 库。如果我们的数字证书是由 Android 认可的 CA 签署的,则可以使用默认的信任管理器来验证证书。要固定连接,只需将主机名和证书公钥的哈希添加到客户端构建器()。有关示例,请参阅此 OKHttp 配方。具有相同主机名和公钥的所有证书都将匹配哈希,因此无需客户端更新即可使用证书轮换等技术。多个主机名 - 公钥元组也可以添加到客户端构建器()。

对于用于签署证书的私钥被泄露的情况,您最终会遇到与您现在试图解决的情况相同的情况,那就是需要发布一个新的移动应用程序来更新您信任的内容。换句话说,公钥不再受信任,因此服务器必须使用您通过移动应用程序发布的备份公钥签名的证书轮换证书。这种方法可以让您有时间发布新版本,删除用于签署受损证书的公钥,而不会锁定所有用户。

您应该始终将备份私钥存储在不同的地方,这样如果其中一个被泄露,您就不会立即全部被泄露,因为那样通过移动应用程序发布备份 pin 是没有用的。

不要这样做

现在,我希望有一种机制来更新这些证书,而无需推出应用程序升级,以防证书过期或私钥被泄露。我该如何实施?

不幸的是,处理私钥泄露的更安全方法是发布一个不再信任它的新移动应用程序。您为更新证书而设计的任何远程解决方案都会为攻击者打开移动应用程序的大门,以替换您所针对的证书。

所以我的建议是不要走这条路,因为你会比你想象的更容易用脚开枪。

我看到的一种可能的解决方案是通过应用程序通知。我可以使用新证书广播通知并将它们存储在客户端中。这种方法有什么问题还是有更好的方法?

虽然移动应用程序已固定连接,但可以绕过它,因此可以执行中间人攻击,并从攻击者的服务器而不是您的服务器检索新证书。请阅读文章固定问题以获取有关绕过它的更多见解:

取消固定的工作原理是在应用程序运行时挂钩或拦截应用程序中的函数调用。一旦被拦截,钩子框架就可以改变传入或传出函数的值。当您使用 HTTP 库来实现固定时,该库调用的函数是众所周知的,因此人们编写了专门挂钩这些检查函数的模块,因此无论 TLS 握手中使用的实际证书如何,它们总是通过。类似的方法也适用于 iOS。

虽然可以绕过证书锁定仍然强烈建议使用它,因为安全性全都与防御层有关,你拥有的越多就越难克服所有这些......如果你想到中世纪,这并不是什么新鲜事城堡,他们是用这种方法建造的。

一种可能的更好方法

但是您还要求提供更好的方法:

这种方法有什么问题还是有更好的方法?

如前所述,您应该锁定证书的公钥,以避免在轮换服务器证书时锁定客户端。

虽然我无法向您指出处理泄露私钥的更好方法,但我可以指出,为了保护证书锁定不被自省框架(如 xPosed 或 Frida)绕过,我们可以使用移动应用证明技术,这将证明真实性的移动应用程序。

弗里达

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

摆姿势

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

在我们进入了移动应用认证技术,我想首先要明确开发者通常的误解,关于WHOWHAT被调用API服务器。

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

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

中间人攻击

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

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

我希望现在你可能已经知道为什么WHOWHAT不一样了,但如果不一样,马上就会明白。

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

身份验证

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

OpenID 连接

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

虽然用户认证可以让API服务器知道世卫组织正在使用的API,它不能保证请求源自什么你期望的那样,移动应用程序的原始版本。

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

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

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

移动应用认证

使用移动应用证明解决方案将使 API 服务器知道发送请求的是什么,从而允许仅响应来自真正移动应用的请求,同时拒绝来自不安全来源的所有其他请求。

移动应用证明服务的作用是在运行时通过在后台运行 SDK 来保证您的移动应用未被篡改或未在有根设备中运行,该 SDK 将与运行在云中的服务通信以证明移动应用程序和设备的完整性正在运行。

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

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

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

因此,该解决方案适用于没有误报的阳性检测模型,因此不会阻止合法用户同时阻止坏人。

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

结论

因此,我建议您切换到通过公钥固定证书,如果您想防止证书固定被绕过和其他威胁,那么您应该设计自己的移动应用证明解决方案或使用准备好即插即用的解决方案。玩。

所以最后,为了保护您的移动 APP 和 API 服务器而使用的解决方案必须根据您要保护的内容的价值和该类型数据的法律要求来选择,例如欧洲的 GDPR 法规.

你想多走一英里吗?

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

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