移动应用程序中的客户端 SSL 证书有多安全?

Posted

技术标签:

【中文标题】移动应用程序中的客户端 SSL 证书有多安全?【英文标题】:How safe are client SSL certificates in a mobile app? 【发布时间】:2012-04-03 12:29:37 【问题描述】:

我希望在我的 android/ios 应用和可访问 Internet 的后端服务之间进行安全通信,因此我正在研究 HTTPS/SSL。

如果我创建自签名证书,然后将客户端证书放入应用程序并导致后端服务要求那个客户端证书,这真的安全吗

这就是我要问的原因。似乎可以通过询问 .apk 来“破解”客户端证书。客户端证书只是一个字符串常量,对吧?这意味着任何人都可以使用客户端证书访问我的后端。 .apk(和 iOS 等效文件)是否足够不透明以防止发现客户端证书

【问题讨论】:

您所说的“只使用普通的受信任证书”是什么意思?这就是你正在做的,不是吗? 我把问题改了。告诉我是否更清楚。 别忘了我们有一个处理这类问题的网站...Information Security。如果有人想举报的话,这里就是主题...... 【参考方案1】:

您是否使用 SSL 证书进行客户端身份验证?并不是说这个问题真的很重要。攻击者可以访问您存储在应用程序中的任何私钥。每个客户端都应该有自己的证书和密钥对,以防止大规模泄露。您的服务器还应该强制执行保护措施,确保受感染的客户端不能只请求任何内容。

这适用于任何身份验证方案。如果您嵌入密码、API 密钥、解密密钥等。设备上的任何东西都应该被认为是可访问的。

证书增加的安全性部分来自于没有暴力破解。如果您为每个客户端使用用户名/密码路由,则可以猜出密码。与 API 密钥相同(尽管它们更长更难)。使用证书,这是一种完全不同的攻击类型,也是一个相当困难的问题。

但是,最重要的是,后端服务不应允许应用程序执行通常不会执行的任何操作。

现在,处理证书,您将遇到一大堆其他问题。您可能希望使用自签名 CA 证书签署每个客户端证书。根据您的用例,管理该 CA 证书可能会有问题。您是要即时生成这些客户端证书,还是自己手动生成?意思是,这是一个百万人可以下载的应用程序,你需要一个自动生成它们的系统吗?或者这是您个人将处理生成证书的私有/内部应用程序?

【讨论】:

【参考方案2】:

证书是无害的。需要保护的是私钥,它只和设备本身一样安全,并不安全。与应用程序一起分发证书和私钥仅意味着拥有该应用程序的任何人都拥有密钥,因此它不会为您提供任何安全性。我认为您需要某种安装后注册步骤。

【讨论】:

“我认为您需要某种安装后注册步骤...” - 另见Simple Certificate Enrollment Protocol (SCEP)。它被广泛采用,但从未标准化。 Peter Gutmann 最近从思科手中接过了火炬,并试图将其标准化。 “任何拥有该应用程序的人都有密钥,因此它不会为您提供任何安全性......” - 这是真正的问题。它被称为“无人值守密钥存储” 问题。这是一个棘手的难题。另请参阅 Gutmann 的 Engineering Security 书。【参考方案3】:

通常,客户端 SSL 证书存储在密钥库中(在 Android 的情况下为 BKS 格式),并且密钥库作为资源包含在您的 APK 中。密钥库被加密并使用密码保护。因此,该客户端证书无法从 APK 中轻松提取,因为它以加密形式存储。

现在...你对密码做了什么?这是问题的症结所在,您有两种选择。

如果您希望您的应用程序能够在没有用户交互的情况下与服务器通信(以便能够访问证书),您需要将密码嵌入到您的应用程序中,然后,是的,攻击者可以反转设计您的代码以找到它,获取密钥库,然后对其进行解密以恢复证书。您可以应用诸如混淆代码之类的技术,以便攻击者更难这样做,但这只会减慢某人的速度而不是阻止它。

您的替代方法是在您的应用程序每次与服务器通信时提示用户输入密码,并使用该密码来解密密钥库(或询问应用程序何时启动并将证书缓存一段时间)。这里的好处是,如果有人对您的 APK 进行逆向工程,他们会找到加密的密钥库并且没有密码,因此您的证书是安全的。缺点是让用户提供密码。

哪种方法最好?这完全取决于您关注的数据的敏感性以及您愿意接受的风险水平。只有你能回答这个问题。

【讨论】:

请注意:如果用户是攻击者,提示输入密码并不能解决问题。 私钥是加密的,而不是证书。除非私钥也泄漏,否则泄漏证书没有风险。【参考方案4】:

Daniel Guillamot,我发现了一些技巧:

拆分服务器端密钥。将 SSL 密钥的密码设置为 string-in-app XOR string-fetched-from webservice 的结果。 通过调用一些应用程序函数来创建应用程序中的字符串,而不是硬编码字符串。 拒绝在应用程序运行时对其进行跟踪,以避免有人在调用私钥解密时获取最终密码。参考:http://books.google.no/books?id=2D50GNA1ULsC&lpg=PA294&ots=YPQQ7DLjBD&dq=The%20example%20just%20shown%20demonstrates%20how%20calls%20to%20ptrace%20can%20be%20hijacked&hl=no&pg=PA293#v=onepage&q&f=false

如果有人有其他想法,我很乐意听到更多。

【讨论】:

丹尼尔的回答并不是真正的回答,更多的是评论,在某种程度上你的回答也是如此......【参考方案5】:

APK 可以被访问和复制,因此在其中放入任何内容都无济于事。安装后需要激活并可能将证书绑定到设备。例如,可以通过将设备的 IMEI 放入证书扩展名之一并通过您的应用程序将 IMEI 与证书一起传递(或者,更好的是,通过 IMEI 在身份验证后并建立安全通道)。

【讨论】:

IMEI 不安全:它可能被克隆。

以上是关于移动应用程序中的客户端 SSL 证书有多安全?的主要内容,如果未能解决你的问题,请参考以下文章

详解SSL证书中的SSL握手协议

SSL证书有多重要?看完这篇文章你就明白了

手机网站需要安全SSL证书吗?

什么是SSL加密?

自己做的ssl证书和ca证书有啥区别

为啥我的SSL证书验证失败