服务器如何验证iPhone应用程序(代码,而不是用户)?

时间:2010-03-18 08:25:58

标签: iphone authentication

假设我有一个涉及iPhone应用程序的解决方案,该应用程序生成一些信息,然后将该信息发送到Web服务进行处理。重要的是,只允许处理来自此特定iPhone应用程序实例的请求(许多不同用户可能会使用该应用程序的许多实例,但我希望确保它们都使用我信任的代码)。换句话说,我想确保我的iPhone应用程序不能(轻松)被其他客户端模仿。你会怎么做?

7 个答案:

答案 0 :(得分:3)

所有其他答案都提供合法的方式来提供一些额外但不完美的安全性。您应该事先了解(因为没有其他人如此明确),不可能提供理论上安全的通信,以便您的服务器始终可以验证另一端的客户端是购买的副本您的应用程序在受制裁的硬件上运行。你无法做到这一点,因为无论Apple内置了什么硬件级安全性来启动信任链(这对他们来说实际上都是可能的),它们都不会暴露给你。

因此,您的策略应该是“许多障碍”之一,一些更大,一些更小,旨在阻止不同程度的攻击复杂性和攻击者的复杂性。有关一些好主意,请参阅此问题的其他答案。你需要多少障碍,以及复杂程度,完全取决于攻击成功的成本(经济,信任等等)。

还要考虑如果你可以避免“可重现的”安全攻击,那你就会更好。换句话说,如果某人破坏了您的应用程序/协议,并且其他人的数据对于每个副本/实例都是相同的,那么您会遇到更多麻烦,因为指令/密钥可以只发布到Web上某处。如果你能想出一种让每个副本/客户端都独一无二的方法,那么你可以在服务器上观察,最糟糕的是,切断已知的破碎客户端等等。(这在iPhone平台上很难。)

答案 1 :(得分:2)

另一种可能性是向应用程序询问应用程序包的某些部分内容 - 类似于应用程序可执行文件的字节59967,或包含的plist或xib。通过保持文件名和位置完全随机,任何欺骗都必须嵌入您的应用程序的整个副本 - 这使得很容易确定它们是否欺骗您的应用程序,并且可能很容易谷歌出现。

您基本上只是让客户端为您提供版本号,并且在服务器上您将拥有所有公共版本的所有文件的副本以检查答案(并确定要发送的挑战)。

由于实际上无法阻止这种情况,下一个最好的事情是尽可能地将欺骗检测视为易于扫描,因此我会考虑帮助您解决问题的解决方案,而不是试图阻止不可阻塞(虽然一些微不足道的初始阻止将阻止riff-raff)。

基本上,你需要更多的层而不是一个真正的硬层。

答案 2 :(得分:1)

您可以在应用中隐藏用于challenge-response authentication的私钥。

如果这个答案太短/抽象,请留下评论,我会更详细地解释。

修改

我想补充一点,我认为没有一种安全(如反向生成安全)的方式来执行所描述的身份验证。但在安全方面,我发现自己经常犯错误。

答案 3 :(得分:1)

您的应用程序生成的任何传出通信都可以在以后截获并重播。如果您想要合理地确定请求来自您的应用程序,您可以执行诸如在您的应用程序中嵌入公共(非私人)密钥并使用它来签署您的通信。但是,在这种情况下,除了提供不可否认性之外,私钥和公钥不会做任何事情(即,证明只有预期的收件人才能阅读该消息,因为它们是唯一一个具有匹配对的一半的密钥对)。

您正在寻找的是提供真实性。您可以执行诸如执行DH密钥交换(http://en.wikipedia.org/wiki/Diffie-Hellman_key_exchange)以生成共享密钥(因为通过在应用程序中对密码进行硬编码并不确保它是秘密),然后使用该秘密执行特定操作你的消息(虽然这仍然不是完美的真实性)。

或者你可以做一些事情,例如检查你的应用程序的代码签名,并验证它是一个合适的签名,它是你的应用程序,或类似的东西。

也许Graham Lee会弹出并给出更好的答案。 :)

修改

(大声思考)以下是一个想法:一旦您的应用程序在商店中,您可以提取发布应用程序的代码签名,将其放在您的服务器上,并在挑战响应中使用它。当您的客户端连接到服务器时,您的服务器可以生成随机值并将其发回。客户端可以使用应用程序的内置代码签名操作该值,并返回操纵值。同时,您的服务器可能正在做同样的事情。当服务器获得操纵值时,它可以将其与其版本进行比较,然后根据它们是否匹配来终止/继续连接。从技术上讲,这可能仍然是欺骗(另一个应用程序可以窃取代码签名并自己使用它),但似乎它更安全。

答案 4 :(得分:1)

我回答了一个类似的问题:

Restricting access to server to iPhone app

我最终做的是使用随机生成的用户名(GUID)。然后,我接受用户名,附加一个秘密(在我的应用程序中硬编码,在服务器上镜像),并将结果作为SHA1,并将其作为密码发送。

在服务器上,我使用给定的用户名,附加相同的秘密,哈希,并将其与客户端发送的内容进行比较。请注意,这需要通过SSL发送,以确保远程安全。

另一种方法是将SSL客户端证书与您的应用程序包一起发送,并将您的服务器配置为仅接受来自具有该证书的客户端的连接。

这两者的弱点在于,如果您的应用程序被破解,提取秘密或客户端证书是微不足道的。

如果您的担忧是未付费的 - 客户使用您的服务器资源,则会遇到完全不同的问题,因为您的主要威胁模型是在越狱手机上运行的应用的盗版副本。有关一些对策,请参阅我的问题的答案。

答案 5 :(得分:1)

当应用启动时,向服务器发送令牌请求。然后让服务器通过APNS向客户端发送令牌(只是一些秘密的,新生成的字符串)。所有后续通信都使用该令牌进行身份验证您甚至可以使用Keychain iPhone端“安全地”保留令牌。在你想要的限制中,确实是不可能的,但这样你就更依赖Apple的工具。

答案 6 :(得分:0)

使用您的设备ID ...发送带有请求的设备ID ...每个iPhone都有唯一的设备ID