让我尝试将您的问题细分为多个子问题/假设:
假设:
a) Keychain 是安全的地方
实际上,并不那么安全。如果您的应用程序安装在越狱设备上,黑客将能够从 keychain 中获取您的密钥。
问题:
a) 有没有办法将某些密钥放入应用程序(从 AppStore 提供的二进制文件)中并完全安全?
简短的答案是否定的。只要二进制文件中有任何东西,它就可能被反向工程。
b) 混淆是否有帮助?
是的。它将增加黑客找到答案的时间。如果您在应用程序中拥有的密钥的“成本”比反向工程所需的时间少 - 一般而言,您就安全了。
但是,在大多数情况下,安全通过混淆是不好的实践。它让你觉得你很安全,但实际上你并不安全。
因此,这可能是安全措施之一,但您需要采取其他安全措施。
c) 在这种情况下应该怎么做?*
在不知道您要做什么的背景下,很难为您提供一个好的解决方案。
例如,为什么每个人都应该访问同一个 Amazon S3?他们需要只读还是写(如 Kendall Helmstetter Gein 指出的那样)。
我认为最安全的情况之一可能是:
- 您的应用程序应该受到密码保护
- 第一次进入应用程序时,它会请求用户进行身份验证(输入用户名、密码)到服务器
- 这将对您的服务器或其他身份验证提供程序进行身份验证(例如 Google)
- 服务器向设备发送某些身份验证令牌(通常是某种类型的 cookie)。
- 您根据应用程序密码的哈希值加密此令牌,并以此形式保存在 keychain 中
- 现在你可以做以下两件事之一:
- 将特定的密钥从服务器交给客户端(这样每个客户端都有自己的密钥),并使用应用程序密码哈希加密它们
- 在服务器上处理所有与S3的操作(并要求客户端发送)
这种方法可以保护您免受多种可能的攻击。
c) 哇哦....我不打算实现你刚才写的所有东西,因为这将花费我的数月时间。有更简单的方法吗?
如果每个客户端都有一组密钥,那么这将是有用的。
如果即使这也太麻烦了,那么就从服务器下载加密的密钥,并以加密形式保存在设备上,并在应用程序中硬编码解密密钥。我会说这是最低侵入性的,至少你的二进制文件里没有密钥。
P.S. Kendall和Rob都是对的。
更新1(基于新信息)
首先,您看过应用内购买编程指南吗?
在服务器产品模型下有非常好的绘图。这个模型可以防止未购买新级别的人。你的应用程序中不会嵌入任何亚马逊密钥,当它收到购买收据时,你的服务器端将交付级别。
没有完美的解决方案来防止某些人(购买了内容并决定从您的应用程序中删除它)的情况,因为在最后一天,您的应用程序将下载到设备上,并且在某个时间点需要以明文(未加密形式)使用它。
如果您真的担心这种情况,我建议您加密所有资产,并以加密形式从服务器交付它们和加密密钥。每个客户端都应该生成一个加密密钥,并使用它来加密资产。
这不会阻止任何高级黑客,但至少它会保护免受某些人使用iExplorer并只复制文件的攻击(因为它们将被加密)。
更新2
关于更新1,还有一件事情需要注意。你应该将文件以未加密的形式存储,并将加密密钥存储在某个地方(例如钥匙串)。
如果你的游戏需要联网,则最好不要在设备上存储加密密钥。每次启动应用程序时,可以从服务器获取该密钥。