假设我需要从iPhone应用程序访问Web服务.此Web服务要求客户端对HTTP请求进行数字签名,以证明应用程序"知道"共享密钥; 客户端密钥.请求签名存储在HTTP头中,请求只是通过HTTP(而不是HTTPS)发送.
这个密钥必须始终保密,但需要iPhone应用程序使用.
那么,鉴于您始终被告知永远不会在客户端存储任何敏感内容,您将如何安全地存储此密钥?
普通用户(99%的用户)很乐意使用该应用程序.会有某个人(一个敌人?)想要这个秘密客户密钥,以便通过冒充来对服务或客户密钥所有者造成伤害.这样的人可能越狱他们的手机,访问二进制文件,运行"字符串"或十六进制编辑器并四处寻找.因此,仅将密钥存储在源代码中是一个糟糕的主意.
另一个想法是将密钥存储在代码中而不是字符串文字中,而是存储在从字节文字创建的NSMutableArray中.
可以使用钥匙串,但由于iPhone应用程序永远不必提供密码来存储钥匙串中的东西,我担心有权访问应用程序沙箱的人可以并且能够简单地查看或轻松解码其中的项目.
编辑 - 所以我读到了关于钥匙串的信息:"在iPhone OS中,应用程序总是可以访问自己的钥匙串项目,并且无法访问任何其他应用程序的项目.系统会为钥匙串生成自己的密码,并存储密钥在设备上以任何应用程序都无法访问它."
所以也许这是存放密钥的最佳位置....如果是这样,我如何使用预先输入到应用程序钥匙串中的密钥?那可能吗?否则,如果没有密钥在源代码中,你怎么能在第一次启动时添加密钥?嗯..
编辑 - 提交的错误报告#6584858在http://bugreport.apple.com
谢谢.
最终目标是限制Web服务对授权用户的访问,对吧?如果您控制Web服务(如果不这样 - 将其包装在您可以控制的Web服务中),则非常容易.
1)创建公钥/私钥对.私钥在Web服务服务器上运行,该服务器放在地牢中并由龙守卫.公钥随即打开.如果有人能够读取公钥,这不是问题.
2)让应用程序的每个副本生成唯一标识符.你如何做到这一点取决于你.例如,您可以在下载时将其构建到可执行文件中(这可能适用于iPhone应用程序)吗?你可以使用手机的GUID,假设他们有办法计算一个.如果你真的想要,你也可以在每个会话中重做一次.
3)使用公钥加密"我的唯一标识符为$ FOO,我批准了此消息".每次请求提交给Web服务.
4)Web服务解密每个请求,弹出任何不包含有效标识符的请求.您可以在此处执行任意或少量工作:保留白名单/黑名单,监控每个标识符的使用情况并调查可疑行为等.
5)由于现在永远不会通过网络发送唯一标识符,因此唯一的妥协方法是对手机进行物理访问. 如果他们可以对手机进行物理访问,则您将无法控制手机上的任何数据.总是.无法帮助.这就是为什么我们建立这样一个系统,以便妥协一部手机永远不会损害一个以上的帐户.
6)构建业务流程以满足以下需求:a)从滥用它的用户移除访问权限; b)恢复对手机遭受物理攻击的用户的访问权限(除非用户是,否则这将非常非常罕见)对手).
简单的答案是,就像今天的情况一样,不可能在iPhone上保守秘密.越狱的iPhone只是一款适合您手中的通用电脑.您无法访问可信平台硬件.用户可以欺骗您可以想象的任何东西,以唯一地识别给定的设备.用户可以将代码注入到您的流程中,以执行检查钥匙串等操作.(搜索MobileSubstrate看看我的意思.)抱歉,你被搞砸了.
在这种情况下,一缕光线就是应用购买收据.如果您使用应用内购买在应用中销售商品,则会收到加密签名的收据,并且可以通过Apple按需验证.即使你不能保持收据的秘密,也可以追踪(由Apple,而不是你)特定的购买,这可能会阻止海盗分享它们.您还可以基于每个收据限制对服务器的访问,以防止您的服务器资源被盗版者耗尽.