2014-02-17 118 views
3

我有一个iOS应用程序,也是我迄今用来管理apns(Apple推送通知)的小型后端。注册过程只是一个带有参数的GET调用,并且由于没有'身份验证'或任何其他类型的控制,所以我担心任何人都可能仅仅使用虚假设备注册来超载我的后端。如何保护应用程序 - 后端通信?

所以主要问题是:如何在没有身份验证的情况下使这种应用程序发送信息到后端传输安全?

这使我想起使用令牌注册设备时,应用程序必须提供正在产生某种HASH的一个简单的想法...

回答

7

有没有办法彻底解决这个问题。无法知道它是您的应用程序正在连接。你所能做的只是添加一点混淆。

你最好的第一步是使用SSL with a pinned certificate来使中间人攻击更难。客户端证书可以提供帮助,但是设置起来有点痛苦,并且不会通过其他解决方案来购买很多。

如果您拥有固定证书和SSL,则只需发送共享密钥和GET一起就可以满足您的需要。将发布的秘密更改为发布,以便让旧的发布。如果有人对您的应用程序进行了反向设计,足以击败固定证书(或直接读取共享密钥),那么他们也将打破所有其他方法。

即便如此,这里有一些更是添加一些额外的层:

Bidirectional shared-secret verification with AES是一个很好的和简单的方法,但需要握手(即你不能用一个单一的GET做到这一点)。你当然可以实现这种单向(所以服务器验证密钥,但不是客户端),但你仍然需要握手。

如果你想保持你的认证令牌到一个单一的GET并且不能固定你的SSL证书,并且你可以使你的GET幂等(好的REST调用应该是这样),那么这是一个简单的实现:

  • 构建GET请求
  • 计算HMAC(SHA-256,共享秘密,得请求,16个字节)
  • 发送HMAC与GET请求

在iOS上沿,这看起来所以方法如下:

NSData *key = ...random 32 bytes shared with server...; 
NSURLRequest *request = ...; 

// Allocate some memory for the HMAC 
NSMutableData *hmac = [NSMutableData dataWithCapacity:CC_SHA256_DIGEST_LENGTH]; 

// Convert your URL into data. This assumes that this is a GET request, so the URL 
// has everything. This also assumes that the GET is idempotent, so if someone 
// replays this GET request, you don't care. 
NSData *requestData = [[[request URL] absoluteString] dataUsingEncoding:NSUTF8StringEncoding]; 

// Compute the HMAC 
CCHmac(kCCHmacAlgSHA256, 
     [key bytes], 
     [key length], 
     [requestData bytes], 
     [requestData length], 
     [hmac mutableBytes]); 

// Truncate the HMAC (this is common practice. It's slightly better, and at least no 
// worse, to send half the HMAC rather than the whole HMAC). 
NSData *token = [hmac subdataWithRange:NSMakeRange(0, [hmac length]/2)]; 

NSURLRequest *finalRequest = ... add the token to your request ... 

你当然会在服务器端计算相同的东西。您可以将其视为“签署GET”。如果你的请求不是幂等的,那么你应该正在努力解决这个问题。如果你无法解决这个问题,你可以把一个时间戳集成到哈希中,并丢弃过时或以前见过的请求。 (在这样做的时候,你已经使你的GET幂等......)

当你升级你的应用时,你应该改变你的共享密钥。这样你可以最终使已发现的旧共享秘密变老。

是的,这些都可以被反向设计。 试图验证应用程序(而不是用户)的任何东西都可以进行反向设计。所以保持简单,并且更多地关注如果它确实发生,你将如何恢复。

如果可能,请添加用户验证。它更强大。

+0

谢谢,这是更完整的答案!标记为正确的答案... – apascual

1

哈希想法应该工作(未成年人注意,SHA-256止跌不存在冲突,MD5不再安全),但它取决于权衡,如果服务涉及真正非常重要的事情,客户端SSL证书将是最好的处理方式。

+0

谢谢,我对客户端证书的恐惧是,最终应用程序可能会被反编译,然后证书将不再可靠......我是对的吗? – apascual

+0

您可以放弃任何不是来自iOS设备的HTTP GET请求(这应该缩小可能生成服务器端处理的请求的数量),您只需要在后端应用程序中捕获http标头。 – theMarceloR

+2

但是任何人都可以在请求中伪造用户代理,因此您不能分辨是否存在真正的iOS设备... – apascual

1

设备上的任何内容都可供确定的攻击者使用。

我会在设备上从相关令牌生成一个哈希值,并在注册APN令牌时将其发送到您的后端。使用HTTPS。

如果有人想用虚假注册重载后端,他们至少不得不反编译应用程序以查看哈希如何生成。

让服务器在设备注册时根据令牌检查哈希。

用注册保存设备的IP地址和时间戳。如果您发现来自同一个IP号码的注册数量不合理,请暂停注册,并对情况进行人工审查。如果一切正常,请发布注册。

+0

谢谢你的回答和伟大的想法! – apascual