假设我需要从iPhone应用程序访问Web服务。此Web服务要求客户端对HTTP请求进行数字签名,以证明应用程序“知道”共享密钥;客户端密钥。请求签名存储在HTTP头中,请求只是通过HTTP(而不是HTTPS)发送。
此密钥必须始终保密,但iPhone应用程序需要使用。
那么,鉴于您始终被告知永远不会在客户端存储任何敏感信息,您将如何安全地存储此密钥?
普通用户(99%的用户)很乐意使用该应用程序。会有某个人(一个敌人?)想要这个秘密客户密钥,以便通过冒充来对服务或客户密钥所有者造成伤害。这样的人可能越狱他们的手机,访问二进制文件,运行“字符串”或十六进制编辑器并四处寻找。因此,仅将密钥存储在源代码中是一个糟糕的主意。
另一个想法是将密钥存储在代码中而不是字符串文字中,而是存储在从字节文字创建的NSMutableArray中。
可以使用Keychain,但由于iPhone应用程序永远不必提供密码来存储钥匙串中的东西,我担心有权访问应用程序沙箱的人可以简单地查看或轻松解码其中的物品。
编辑 - 所以我读到了关于钥匙串的内容:“在iPhone OS中,应用程序始终可以访问自己的钥匙串项目,并且无法访问任何其他应用程序的项目。系统会为钥匙串生成自己的密码,并且将密钥存储在设备上,使得任何应用程序都无法访问它。“所以也许这是存放密钥的最佳位置....如果是这样,我如何使用预先输入到应用程序钥匙串中的密钥?那可能吗?否则,如果没有密钥在源代码中,你怎么能在第一次启动时添加密钥?嗯..
编辑 - 提交错误报告#6584858 http://bugreport.apple.com
感谢。
答案 0 :(得分:9)
最终目标是限制授权用户访问Web服务,对吧?如果您控制Web服务非常容易(如果不这样 - 将其包装在您可以控制的Web服务中)。
1)创建公钥/私钥对。私钥在Web服务服务器上运行,该服务器放在地牢中并由龙守卫。公钥随即打开。如果有人能够阅读公钥,这不是问题。
2)让应用程序的每个副本生成唯一标识符。你如何做到这一点取决于你。例如,您可以在下载时将其构建到可执行文件中(这可能适用于iPhone应用程序)吗?你可以使用手机的GUID,假设他们有办法计算一个。如果你真的想要,你也可以在每个会话中重做一次。
3)使用公钥加密“我的唯一标识符为$ FOO,我批准了此消息”。每次向Web服务请求时都提交。
4)Web服务解密每个请求,弹出任何不包含有效标识符的请求。您可以在此处执行尽可能多的工作:保留白名单/黑名单,监控每个标识符的使用情况并调查可疑行为等。
5)由于现在永远不会通过网络发送唯一标识符,因此唯一的妥协方法是对手机进行物理访问。 如果他们对手机具有物理访问权限,则您将无法控制手机上的任何数据。总是。无法帮助。这就是为什么我们建立这样一个系统,以便妥协一部手机永远不会损害一个以上的帐户。
6)构建业务流程以满足以下需求:a)删除滥用它的用户的访问权限; b)恢复对手机遭受物理攻击的用户的访问权限(这将是非常非常罕见的,除非用户是对手)。
答案 1 :(得分:7)
简单的答案是,就像今天的情况一样,不可能在iPhone上保守秘密。越狱的iPhone只是一款适合您手中的通用电脑。您无法访问可信平台硬件。用户可以欺骗您可以想象的任何东西,以唯一地识别给定的设备。用户可以将代码注入到您的流程中,以执行检查钥匙串等操作。 (搜索MobileSubstrate看看我的意思。)抱歉,你搞砸了。
在这种情况下,一缕光线就是应用购买收据。如果您使用应用内购买在应用中销售商品,则会收到加密签名的收据,并且可以通过Apple按需验证。即使你不能保持收据的秘密,可以跟踪(由Apple,而不是你)到特定的购买,这可能会阻止海盗分享它们。您还可以基于每个收据限制对服务器的访问,以防止您的服务器资源被盗版者耗尽。
答案 2 :(得分:4)
UAObfuscatedString可以解决您的问题。来自文档:
当您编写包含字符串常量的代码时,此字符串将以明文形式保存在二进制文件中。黑客可能会发现漏洞或更改字符串以影响应用的行为。 UAObfuscatedString只在二进制文件中存储单个字符,然后在运行时将它们组合在一起以生成字符串。这些单个字母极不可能在二进制文件中被发现,因为它们将被插入到编译代码中的随机位置。因此,它们似乎是任何试图提取字符串的人的随机代码。
答案 3 :(得分:2)
如果您只能忍受iPhone OS 3.0,您可能需要查看推送通知。我不能详细说明,但您可以向Apple的服务器提供有效负载以及通知本身。当他们接受警报时(或者如果您的应用程序正在运行),则会调用代码的某些部分并存储钥匙串项。在这一点上,这是我能想到的在iPhone上安全存储秘密的唯一途径。
答案 4 :(得分:2)
我有同样的问题,花了很多时间寻找答案。问题是鸡和鸡蛋:如何使用您的应用程序所需的数据预先填充钥匙串。
无论如何,我发现了一种技术,至少会让越狱者更难发现信息 - 他们至少必须反汇编你的代码才能找到你掩饰信息的方法:
String Obfuscation(如果链接中断搜索“Obfuscate / Encrypt a String(NSString)”)
基本上,在放入应用程序之前对字符串进行模糊处理,然后使用代码对其进行取消混淆。
它比什么都不做要好。
大卫
编辑:我实际上是在应用程序中使用它。我将一个基本编码字符串放入info.plist中,然后在代码中对它进行了几次操作 - rot13,旋转/反转字节等。最后处理的字符串用于解码混淆的字符串。现在,三个字母的代理商可以肯定打破这个 - 但是花费了很多时间来解码二进制文件。我想说这是我遇到过的最好的技巧,但我只是阅读了Kiran关于 UAObfuscatedString (不同答案)的帖子,这是一种完全不同的混淆方式。它的好处是在应用程序的任何地方都不会保存任何字符串 - 每个字母都会转换为方法调用。选择器将显示为字符串,因此黑客可以快速告诉您的类使用了该技术。
答案 5 :(得分:0)
我认为this similar question,和我的answer,也可能与您的案件相关。简而言之,有一些关于iPhone中存在可信平台模块的讨论。这将允许您的服务信任iPhone,即使是在攻击者的手中。但是,看起来使用钥匙串是最好的选择。
答案 6 :(得分:0)
您是否考虑/尝试推送通知建议,以便最初将秘密传输到应用程序&钥匙扣?或者最终找到其他方法来实现这个目标?
答案 7 :(得分:0)
我要将我的iphone app上传图片到Amazon S3。我没有将AWS凭证放在应用程序中,而是将应用程序电话放在我的服务器上,以便在S3上传请求中使用URI和标头。我的服务器将生成S3 URI,正确的签名等。然后,我可以在我的应用程序的Web服务上实现比AWS提供的更严格,更具体的安全模型,而不是将我的AWS密钥泄露给任何拥有越狱iphone的人。
但是仍然必须给予应用程序一些信任(凭据或其他),并且该信任可能被盗。 所有你能做的就是限制如果有人越狱iphone并窃取应用程序中的任何凭据所造成的损害。这些凭据越强大,最糟糕的事情就是。限制凭证权力的方法包括:
答案 8 :(得分:-1)
听起来不错。将使用HTTPS和可能的加密包来处理密钥。
我认为CommonCrypto适用于iPhone。
编辑:听起来还不错。为什么有人会在HTTP标头中传递密钥?任何跟踪网络流量的人(例如通过记录wifi路由器)都会看到它。有加密消息流量的完善的安全方法......为什么不使用它们而不是发明什么基本上是一个简单的有缺陷的系统?
编辑二:啊,我明白了。我会继续使用Keychain ...我认为它仅适用于这类情况。我错过了你使用密钥生成请求。如果可以的话,仍然会使用HTTPS,因为这样你就不会冒险通过检查足够的签名来推断你的密钥生成方案。答案 9 :(得分:-1)
如果可能的话,我建议在运行时创建一个密钥。这样,如果密钥在特定会话期间被逮捕,一旦会话结束,密钥将毫无价值。如果他们足够聪明,他们仍然可以从记忆中理解密钥,但是由于密钥在一段时间后会变得无效,所以无关紧要。