43

我试图隐藏我在我的一个应用程序中使用的 2 个秘密。

据我了解,钥匙串是个好地方,但在提交应用程序之前我无法添加它们。

我想到了这个场景——

  • 通过将秘密传播到其他实体中以隐藏它们,在我的应用程序的 CoreData 数据库中预先播种秘密。(我已经在那个应用程序中有一个种子数据库)。
  • 当应用程序首次启动时,生成密钥并将其移动到钥匙串。
  • 从 CoreData 中删除记录。

这是安全的还是黑客可以看到这种情况并获得这些密钥?

*第三次编辑**抱歉没有从一开始就解释这个场景 - 该应用程序有很多级别,每个级别都包含文件(音频、视频、图像)。用户可以购买一个级别(IAP),购买完成后,我需要将文件下载到他的设备上。

对于 iOS6,文件使用 Apple 新的“托管内容”功能存储。对于 iOS5,文件存储在 amazon S3 中。

因此,在所有这些过程中,我有 2 个密钥: 1. IAP 密钥,用于验证在 Apple IAP 上的购买。2. S3 密钥,用于为 iOS5 用户从 S3 获取文件:

NSString *secretAccessKey = @"xxxxxxxxx";
NSString *accessKey = @"xxxxxxxxx";

我需要保护这些密钥吗?恐怕人们无需购买关卡就可以从 S3 获取文件。或者黑客将能够构建一个预先下载所有级别的黑客版本。

4

3 回答 3

72

让我尝试将您的问题分解为多个子问题/假设:

假设:

a) 钥匙扣是安全的地方

实际上,它并不那么安全。如果您的应用程序安装在越狱设备上,黑客将能够从钥匙串中获取您的密钥

问题:

a) 有没有办法将一些密钥放入应用程序(从 AppStore 交付的二进制文件)并完全安全?

简短的回答是否定的。只要您的二进制文件中有内容,就可以对其进行逆向工程。

b) 混淆会有帮助吗?

是的。这将增加黑客弄清楚它的时间。如果您在应用程序中拥有的密钥“花费”的时间少于逆向工程所花费的时间 - 一般来说,您很好。

但是,在大多数情况下,通过默默无闻来确保安全是一种不好的做法,它让您感觉自己很安全,但实际上并非如此。

因此,这可能是安全措施之一,但您也需要采取其他安全措施。

c) 在这种情况下我应该怎么做?*

在不知道您要做什么的背景下,很难为您提供一个好的解决方案。

例如,为什么每个人都应该可以访问相同的 Amazon S3?他们需要只读还是写(正如 Kendall Helmstetter Gein 指出的那样)。

我相信最安全的场景之一是这样的:

  • 您的应用程序应受密码保护
  • 第一次进入应用程序时,它会要求用户向服务器进行身份验证(输入他的用户名、密码)
  • 这会针对您的服务器或其他身份验证提供商(例如 Google)进行身份验证
  • 服务器向设备发送一些身份验证令牌(通常是某种类型的 cookie)。
  • 您根据应用程序密码的哈希加密此令牌并以这种形式将其保存在钥匙串中
  • 现在你可以做以下两件事之一:
    • 将特定密钥从服务器移交给客户端(因此每个客户端都有自己的密钥)并使用应用程序密码的哈希对其进行加密
    • 在服务器上使用 S3 处理所有操作(并要求客户端发送)

这样您就可以免受多种可能的攻击。

c) 哇哦....我不打算实现你刚刚写的所有这些东西,因为这需要我几个月的时间。有没有更简单的?

我认为这会很有用,如果您每个客户端都有一组密钥。

如果这太多了,那么从服务器下载加密密钥并将它们以加密形式保存在设备上,并将解密密钥硬编码到您的应用程序中。我会说它是微创的,至少你的二进制文件中没有密钥。

PS Kendall 和 Rob 都是对的。

更新 1(基于新信息)

首先,你有没有在应用购买编程指南中看到。

服务器产品模型下有很好的绘图。这种模式可以防止没有购买新关卡的人。您的应用程序中不会嵌入亚马逊密钥,并且您的服务器端将在收到购买收据时移交关卡。

没有完美的解决方案可以防止购买内容的人(并决定从您的应用程序中窃取它),因为最终您的应用程序会将内容下载到设备上,并且需要以纯格式(未加密的形式) ) 在某个时间点。

如果您真的担心这种情况,我建议您对您的所有资产进行加密,并将其与加密密钥一起从服务器以加密形式移交。应为每个客户端生成加密密钥,并应使用它对资产进行加密。

这不会阻止任何高级黑客,但至少它可以防止有人使用 iExplorer 并复制文件(因为它们将被加密)。

更新 2

关于更新 1 的另一件事。您应该存储未加密的文件并将加密密钥存储在某处(例如,在钥匙串中)。

如果您的游戏需要互联网连接,最好不要在设备上存储加密密钥。每次启动应用程序时,您都可以从服务器获取它。

于 2013-02-14T00:12:53.533 回答
17

不要在您的应用程序中存储用于写入的 S3 密钥!在短时间内,嗅探流量的人将看到对 S3 的写入调用,在较短的时间内,他们将找到该密钥并做任何他们喜欢的事情。

应用程序可以以任何程度的安全性将内容写入 S3 的唯一方法是通过您控制的服务器。

如果它是用于只读使用的密钥,这意味着您的 S3 无法公开读取,但该密钥可用于只读访问而无法写入,那么您可以将其嵌入应用程序中,但任何人都可以拉取它出去。

为了稍微掩盖预加载的敏感数据,您可以将其加密在一个文件中,应用程序可以将其读入内存并在存储到钥匙串中之前解密。同样,有人将能够获得这些密钥,所以如果他们可以,最好不要紧。

编辑:

根据新信息,您最好将秘密嵌入代码中。使用 iExplorer 之类的工具,普通用户可以轻松访问核心数据数据库或应用程序包中的任何其他内容,但目标文件在某种程度上是加密的。如果他们有越狱设备,他们可以很容易地获得未加密的版本,但仍然很难找到有意义的字符串,也许将它们分成两部分并在代码中重新组合。

同样,它不会阻止一个坚定的黑客,但足以让大多数人远离。

您可能还想添加一些代码,这些代码会尝试询问您的服务器是否可以下载任何覆盖机密。这样,如果机密被泄露,您可以通过更改用于您的应用程序的机密来快速做出反应,同时阻止任何使用复制机密的人。首先将没有覆盖下载。您不希望必须等待应用程序更新才能使用新密钥。

于 2013-02-13T23:27:14.973 回答
11

没有好的方法可以在您发送给攻击者的一段代码中隐藏一个秘密。与大多数此类事情一样,您需要更多地关注如何在密钥泄漏时缓解问题,而不是花费无限时间试图保护它。例如,为每个用户生成不同的密钥允许您在密钥被滥用时禁用它。或者通过中间服务器工作可以让您控制协议(即服务器拥有密钥并且只愿意用它做某些事情)。

做一点混淆不是浪费时间。没关系。但是不要花太多时间在上面。如果它在程序中并且非常有价值,那么它将被黑掉。专注于如何检测何时发生,以及如何在发生时恢复。并尽可能将此类敏感数据移至您控制的其他服务器中。

于 2013-02-13T23:10:33.790 回答