在iOS应用程序场景中确保密钥安全吗?

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

据我所知钥匙扣是一个好地方,但我不能在我提交应用程序之前添加它们。

我想过这个场景 –

  • 预先在我的应用程序的CoreData数据库中传播秘密,将它们分散到其他实体中以掩盖它们。 (我已经在该应用程序中有一个种子数据库)。
  • 随着应用程序第一次启动,生成并移动到钥匙链的钥匙。
  • 从CoreData中删除logging。

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

*第三编辑**抱歉不从一开始就解释这个情况 – 应用程序有很多层次,每个级别包含文件(audio,video,图像)。 用户可以购买一个级别(IAP),购买完成后我需要将文件下载到他的设备。

对于iOS6,这些文件与Apple新的“托pipe内容”function一起存储。 对于iOS5,文件存储在亚马逊S3中。

所以在这个过程中,我有两个键:1. IAP密钥,用于validation在Apple IAP购买。 2. S3键,用于从S3 for iOS5用户获取文件:

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

我需要保护那些钥匙吗? 我恐怕人们能够从S3中拿到这些文件,而不用购买这些关卡。 或者,黑客将能够构build一个黑客版本的所有级别预先下载里面。

让我试着把你的问题分解成多个子问题/假设:

假设:

a)钥匙扣是安全的地方

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

问题:

a)是否有办法将一些密钥放入应用程序(从AppStore提供的二进制文件)并且是完全安全的?

简短的回答是NO。 一旦你的二进制文件中有东西,就可能被反向devise。

b)混淆会有帮助吗?

是。 这将会增加黑客的时间。 如果您在应用程序中使用的密钥“花费”的时间less于在逆向工程上花费的时间 – 一般而言,您是好的。

但是,在大多数情况下,通过默默无闻的安全性是不好的做法,它会让你感觉到你是安全的,但是你却不是。

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

c)在这种情况下我该怎么办?

不知道背景是什么,很难给你一个好的解决scheme。

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

我相信最安全的scheme之一就是这样的:

  • 你的应用程序应该被密码保护
  • 您第一次input您的应用程序时,它会要求用户对服务器进行身份validation(input他的用户名,密码)
  • 这对您的服务器或其他身份validation提供程序进行身份validation(例如Google)
  • 服务器发送一些身份validation令牌给设备(通常它是某种types的cookie)。
  • 您可以根据应用程序密码的散列值对该令牌进行encryption,并将其保存在此表单的钥匙串中
  • 现在你可以做两件事之一:
    • 将特定的密钥从服务器交给客户端(这样每个客户端都将拥有自己的密钥),并使用应用密码的散列值对其进行encryption
    • 处理服务器上S3的所有操作(并要求客户端发送)

这样可以防止多种可能的攻击。

c)Whoooa ….我不打算执行你刚才写的所有东西,因为这需要几个月的时间。 有什么更简单的吗?

我认为这将是有用的,如果你有一套每个客户端的密钥。

如果即使这样做太多,那么从服务器上下载encryption的密钥,并以encryption的forms保存在设备上,并将解密密钥硬编码到您的应用程序中。 我会说这是微创,至less你的二进制文件没有键。

PS Kendall和Rob都是对的。

更新1(基于新的信息)

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

服务器产品模型下有非常好的绘图。 这种模式可以防止没有购买新水平的人。 在您的应用程序中将没有embedded亚马逊密钥,并且您的服务器端将在收到购买收据时交付级别。

没有完美的解决scheme来防止购买内容的人(并决定将其从应用程序中删除),因为在最后几天,您的应用程序将把内容下载到设备,并将以普通(未encryption的forms)在某个时间点。

在这种情况下,如果您真的担心这种情况,我build议您encryption所有的资产,并以encryption的forms从服务器和encryption密钥一起交付。 应该为每个客户端生成encryption密钥,并且应该使用它encryption资产。

这不会阻止任何高级黑客,但至less它会保护使用iExplorer的人,只是复制文件(因为他们将被encryption)。

更新2

关于更新还有一件事情1.您应该存储未encryption的文件并在某处存储encryption密钥(例如在钥匙串中)。

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

不要在您的应用程序中存储用于写入的S3密钥! 简而言之,有人嗅探stream量会看到对S3的写入调用,按照更短的顺序,他们将find该关键字并执行任何他们喜欢的操作。

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

如果它是一个用于只读使用的密钥,意味着你的S3不能被公开读取,但是这个密钥可以被用于只读访问而没有写入的能力,那么你可以把它embedded到应用程序中,但是任何人都想要把它拉出来出。

要轻轻掩盖预先加载的敏感数据,您可以在文件中对其进行encryption,应用程序可以将其读入内存并解密,然后再存储到钥匙串中。 再次,有人将能够得到这些关键,所以最好不要紧,如果他们可以。

编辑:

基于新的信息,你可能更好的只是将代码中的秘密embedded。 使用像iExplorer这样的工具,一个因果用户可以很容易地到达一个核心数据库或者你的应用程序包中的其他东西,但是对象文件有些encryption。 如果他们有一个越狱设备,他们可以很容易地得到未encryption的版本,但它仍然可能很难find有意义的string,也许将它们存储在两个部分,并重新组装在代码中。

再次,它不会阻止一个坚定的黑客,但它足以让大多数人。

您可能还想添加一些代码,试图询问您的服务器是否存在可以下载的覆盖机密。 这样,如果秘密泄露,您可以通过更改用于您的应用程序的秘密快速做出反应,同时closures任何使用复制秘密的人。 首先,将不会覆盖下载。 您不需要等待应用程序更新才能使用新密钥。

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

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