如何确保仅从我的代码访问我的Web服务?

时间:2009-05-11 16:01:43

标签: iphone security http https

我正在为我的iPhone应用程序编写一个非常简单的Web服务。假设这是一个http页面,它在http://mysite/getRand返回一个随机数。如何确保此页面只能从我的iPhone应用程序访问而不能从其他客户端访问?我曾想过做一些简单的密码机制,但很容易通过捕获我的应用程序发送的内容来嗅探。

这样做的原因是仅允许合法请求来降低我的服务器的负载。

9 个答案:

答案 0 :(得分:11)

你真的不能这样做。您的应用程序可以被反汇编,二进制文件中的任何秘密都可以在恶意应用程序中复制。

您应该注意的另一个攻击是人们将hosts文件设置为他们控制的位置,然后安装允许他们为该域提供签名的根证书。你的申请会带着秘密来发帖,他们只能读出这个秘密。他们可以通过这种方式从二进制文件中的任何复杂加密系统中提取密码。

此线程中的大多数想法都容易受到此攻击。

也就是说,有人照顾你的应用程序的可能性可能相当遥远。

我只是保持简单。拥有一个硬编码到您的应用程序的密码。为了防止有人只是查看资源并尝试每个字符串,请将其作为两个字符串的XOR或特定固定字符串的AES解密结果。

显然,您应该通过SSL执行请求,否则攻击者只能嗅探流量。

是的,一个坚定的攻击者会绕过这个计划,但就像任何DRM计划一样,情况总是如此。诀窍是要付出太多努力才能获得它。

答案 1 :(得分:2)

要跟进Simon的想法,您可以非常轻松地在应用程序中使用密钥字符串,然后使用您的密钥字符串发送设备ID,然后发送DeviceID XOR(或其他一些简单的字符串加密算法)。

由于您知道要使用的密钥值,因此在服务器端“解密”此字符串并验证值是否匹配是微不足道的。

这样,每个用户的设备的密码都不同,并且“密钥”字符串永远不会通过大型未清洗的互联网的线路发送。 : - )

是的,这绝不是不可能弄清楚的,但正如其他人所说,这个想法不是让它变得不可能。这个想法是让它比它的价值更麻烦。

答案 2 :(得分:1)

我也会将https协议与客户端密钥一起使用。您可以为每个人使用一个客户端密钥,或者您甚至可以为每个客户端生成不同的密钥并在服务器上“注册”它们。

我认为对于小型项目来说这是一项很多工作,但如果您需要身份验证,这听起来很合适。

您应该检查手机所有者是否轻易看到按键。请记住,无论如何都有人能够破解它。

答案 3 :(得分:1)

我假设您不想使用SSL?如果您这样做,则可以打开HTTPS会话,然后在请求中传递一些密钥。

如果您不想要SSL,您的选项是有限的:具有伪安全性我建议使用身份验证和授权方法,第三个用于减少总体流量:

身份验证:客户端应用程序中的生成器,它通过与密钥文件组合来创建密钥。密钥文件可以每隔一段时间更新一次以获得更高的安全性:假设您每周更新一次密钥文件。重新上限:生成器将应用程序密钥与应用程序密钥文件结合起来,生成用于身份验证的传输的第3个密钥。然后,服务器就可以进行身份​​验证。

授权:当然你也想锁定流氓应用程序。在这里,最好有与该网站的授权机制。除非客户端登录,否则不要替换密钥文件。跟踪密钥文件给用户。等

减少交通: 如果您收到了淫秽的流量,或者如果您怀疑有人试图DOS服务器,您也可以让服务器和客户端同步,以便在程序生成的URL上进行请求/响应,这些URL可能会经常更改。打开/关闭如此多的HTTPS会话是浪费的,如果有人只是满足于你的请求。

答案 4 :(得分:1)

这是一个想法 - 发送设备ID以及来自您应用的请求。

监控所使用的设备ID - 如果您看到来自不同IP的大量请求接近或同时发送,该设备可能被用作发送给您的请求中的固定密钥 - 阻止它。

对于那些实际从其他应用程序(不是您的应用程序)发送真实设备ID的用户,您可以监控使用趋势,以查看调用是否与应用程序的执行方式相匹配 - 就像设备在初始化之前使用的一个调用一样打电话给你通常会期待的,依此类推 - 阻止它们。

基本上,通过围绕使用模式转换规则,您可以更好地适应尝试使用您的服务的人,确保它不像某些随机使用密钥那样是固定目标。

您可能还想使用简单的使用密钥以及第一道防线,然后在流量分析方法上进行分层。您查找的自定义http标头值也是另一种让天真的攻击者绊倒的简单方法。

答案 5 :(得分:0)

我不确定您使用的是哪种Web技术,但如果您使用的是Ruby on Rails,它会在其所有控制器中使用秘密身份验证令牌,以确保恶意代码无法访问破坏性方法(通过PUSH, POST或DELETE)。您需要将该身份验证令牌发送到请求正文中的服务器以允许其执行。这应该达到我认为你正在寻找的目标。

如果你没有使用Ruby on Rails,那么代码认证方法可能是一个很好的方法,可以用你正在使用的任何技术来研究和实现。

查看Rails Security Guide,特别是第3.1节(CSRF对策)。

答案 6 :(得分:0)

你可以做一些事情,比如从iPhone加密当前时间和IP地址,然后在服务器上解密它。缺点是您需要iPhone应用程序才能知道“秘密”密钥,以便只有它才能生成有效的访问权限...一旦密钥处于疯狂状态,只有时间才能被黑客入侵。应用程序真的值得付出努力。

您可以使用应用程序的一些随机部分来加密响应,该部分意图使用它,在响应的未加密位中指定二进制文件的位置。那么至少只有能够访问你的二进制文件的客户才能解密它......但同样,这几乎不是100%安全的。

最终,您需要问问自己,您希望在保护服务方面投入多少精力,以及您认为黑客会滥用服务的努力程度。

答案 7 :(得分:0)

我不是Cocoa Touch开发人员,但我认为基于SSL的HTTP身份验证很容易实现,而且可能正是您正在寻找的。

您需要做的就是在服务器端设置HTTP身份验证(您没有提到您在服务器端使用的内容)并在您的Web服务器上创建自签名SSL证书。完成。 :)

告诉我们有关您的设置的更多信息,我们将能够为您提供进一步的帮助。

答案 8 :(得分:0)

正如一些答案所述,将您的网络服务关闭给其他人将是一个很大的麻烦。您可以期待的最好的方法是让黑客更容易使用其他网络服务,而不是使用您的服务...

执行此操作的另一个建议是从服务器和客户端上的random seed生成随机数。服务器需要跟踪所有客户端的随机数序列中的位置,并将该数字与客户端发送的数字相匹配。

客户端还必须注册才能访问服务器。这也可以作为认证机制。

所以:

//Client code:
$sequence = file_get_contents('sequence.txt');
$seed = file_get_contents('seed.txt');
$sequence++;

//Generate the $sequence-th random number
srand($seed);
for ($i = 0; $i <= $sequence; $i++) {
    $num = rand();
}
//custom fetch function
get_info($main_url . '?num=' . $num . '&id' = $my_id);

这将产生一个与此类似的请求:

http://webservice.com/get_info.php?num=3489347&id=3

//Server Code: (I'm used to PHP)

//Get the ID and the random number
$id = (int)$_REQUEST['id'];
$rand = (int)$_REQUEST['num'];
$stmt = $db->prepare('SELECT `sequence`, `seed` FROM `client_list` WHERE `id` = :id');
if ($stmt->execute(array(':id' => $id)) {
    list($sequence, $seed) = $stmt->fetch(PDO::FETCH_ASSOC);
}
$sequence++;

//Generate the $sequence-th random number
srand($seed);
for ($i = 0; $i <= $sequence; $i++) {
    $num = rand();
}
if ($num == $rand) {
    //Allow Access
} else {
    //Deny Access
}

通过为每个客户端使用不同的种子,您可以确保黑客无法通过跟踪以前使用过的数字来预测随机数。