如何确保仅通过我的代码访问我的网络服务?

发布于 2024-07-19 17:54:31 字数 270 浏览 5 评论 0 原文

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

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

I am writing a very simple web service for my iPhone app. Let's say this is a http page that returns a random number at http://mysite/getRand. How do I ensure that this page can only be accessed from my iPhone app and not from other clients? I've thought of doing some simple password mechanism but that can easily be sniffed by capturing what my app sends out.

The reason for this is to lower the load of my server by only allowing legitimate requests.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

望她远 2024-07-26 17:54:32

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

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

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

I'm not an Cocoa Touch developer, but I think HTTP Authentication over SSL would be easy to implement and it's probably exactly what you're looking for.

All you need to do is setup HTTP Authentication on the server side (you haven't mentioned what you're using on the server side) and create a self-signed SSL cert on your webserver. Done. :)

Tell us more about your setup and we will be able to help you further.

冬天旳寂寞 2024-07-26 17:54:32

正如一些答案所述,向其他人关闭您的网络服务将是一个主要麻烦。 您所能希望的最好的结果就是让黑客更容易使用其他网络服务,而不是使用您的网络服务...

另一个建议是从 服务器和客户端上的随机种子。 服务器需要跟踪所有客户端在随机数序列中的位置,并将该数字与客户端发送的数字相匹配。

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

因此:

//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
}

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

As some of the answers have stated, closing your web service off to everyone else will be a major hassle. The best you can hope for is to make it easier for the hackers to use another web service, than to use yours...

Another suggestion to do this, is to generate random numbers from a random seed on both the server and the client. The server would need to track where in the sequence of random numbers all of the clients are, and match that number to the one sent by the client.

The client would also have to register to be given access to the server. This would also serve as a authentication mechanism.

So:

//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);

This will generate a request similiar to this:

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
}

By using a a different seed for each client, you ensure that hackers can't predict a random number by tracking previous numbers used.

终陌 2024-07-26 17:54:31

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

您应该注意的另一种攻击是人们将主机文件设置到他们控制的位置,然后安装根证书以允许他们为该域提供签名。 您的应用程序将使用该秘密进行发布,并且他们只能读出该秘密。 他们可以通过这种方式从二进制文件中的任何复杂的加密系统中提取密码。

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

也就是说,有人足够关心地反汇编你的应用程序的可能性可能相当小。

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

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

是的,坚定的攻击者会绕过该方案,但与任何 DRM 方案一样,情况始终如此。 诀窍是让太多的努力变得不值得。

You can't really do this. Your application can be disassembled and whatever secret is in the binary can be replicated in a malicious application.

Another attack you should be aware of is people settings the hosts file to a location they control and then installing a root certificate that allows them to provide a signature for that domain. Your application would do the post with the secret, and they'd just be able to read out the secret. They could extract the password from any complicated encryption system within the binary in this way.

Most of the ideas in this thread are vulnerable to this attack.

That said, the likelihood of somebody caring enough to disassemble your application is probably fairly remote.

I'd just keep it simple. Have a password that's hardcoded in to your application. To prevent someone just looking at the resources and trying every string, make it the XOR of two strings or the result of an AES decrypt of a particular fixed string.

Obviously, you should do the request over SSL otherwise an attacker can just sniff the traffic.

Yes, a determined attacker will circumvent the scheme but like any DRM scheme, that's always been the case. The trick is to make it too much effort to be worth it.

写给空气的情书 2024-07-26 17:54:31

为了遵循 Simon 的想法,您可以很容易地在应用程序中拥有一个密钥字符串,然后发送设备 ID,然后将 DeviceID 与您的密钥字符串进行异或(或用于字符串加密的其他简单算法)。

由于您知道要使用的密钥值,因此在服务器端“解密”该字符串并验证这些值是否匹配对您来说很简单。

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

是的,这绝不是不可能弄清楚的,但就像其他人所说的那样,我们的想法并不是让它变得不可能。 这个想法是让它变得比它值得的更麻烦。

To follow up on Simon's idea, you could very easily have a key string in your application, then send the device ID, and then the DeviceID XOR'ed (or some other simple algorithm for string encryption) with your key string.

Since you know the key value to use, it's trivial for you to "decrypt" this string on the sever side and verify that the values match.

This way, the password is different for each user's device, and the "key" string is never sent over the wires of the great unwashed internets. :-)

Yes, this would by no means be impossible to figure out, but like others have said, the idea is not to make it impossible. The idea is to make it more trouble than it is worth.

假装爱人 2024-07-26 17:54:31

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

我认为对于小型项目来说这需要大量工作,但如果您需要身份验证,这听起来像是合适的事情。

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

I would use the https protocol with client-side keys too. You can use one client key for everyone or you can even generate a different key for each client and "register" them at your server.

I suppose that it's a lot of work for small project, but it sounds like the appropriate thing to do if you need authentication.

You should check that keys aren't seen easily by mobile phone owner. And remember that somebody will be able to hack it in any case.

绝不放开 2024-07-26 17:54:31

这里有一个想法 - 发送设备 ID 以及来自应用程序的请求。

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

对于那些实际从其他应用程序(不是您的应用程序)发送真实设备 ID 的用户,您可以监视使用趋势,看看这些调用是否与您的应用程序的执行模式相匹配 - 就像设备在进行某些初始化调用之前使用的一个调用通常期望,等等 - 也阻止那些。

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

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

Here's one thought - send up the device ID along with requests from your app.

Monitor the device ID's used - if you see a ton of requests from different IP's near or at the same time, that device is probably being used as a fixed key in the requests sent to you - block it.

For those that actually send the real device ID from other apps (not yours), you can monitor usage trends to see if the calls match the pattern of how your app performs - like one call being used by a device before some initialization call you would normally expect, and so on - block those too.

Basically by being able to shift rules around patterns of use, you can better adjust to someone trying to use your service by making sure it's not a fixed target like some random use key would be.

You may also want to use a simple use key as well as a first line of defense, and then layer on the traffic analysis approach. Also custom http header values you look for are another simple way to trip up a naive attacker.

瞎闹 2024-07-26 17:54:31

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

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

身份验证:客户端应用程序中的生成器,通过与密钥文件结合来创建密钥。 为了提高安全性,可以经常更新密钥文件:假设您每周更新一次密钥文件。 回顾一下:生成器将应用程序秘密与应用程序外密钥文件相结合,生成用于身份验证的传输的第三个密钥。 然后服务器就能够进行身份验证。

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

交通减少:
如果您收到大量流量,或者您怀疑有人试图对您的服务器进行 DOS,您还可以让服务器和客户端同步以在程序生成的 URL(可能经常更改)上请求/响应。 如果有人向您发送大量请求,那么打开/关闭如此多的 HTTPS 会话是很浪费的。

I am assuming you don't want to use SSL? If you do then you can open HTTPS session and then pass some secret key in the request.

If you don't want SSL your options are limited: to have pseudo security I suggest both authentication and authorization methods and a third to reduce overall traffic:

Authentication: Generator in client application that creates secret keys by combining with a key file. The keyfile can be updated every so often for greater security: lets say you update the key file once a week. To re-cap: Generator combines in app secret with out of app key file to generate a 3rd key for transmission used in authentication. The server would then be able to authenticate.

Authorization: Of course you also want to lock out rogue applications. Here it would be best to have authorization mechanism with the site. Don't replace keyfiles for unless the client logs in. Track key files to users. etc.

Traffic reduction:
If you are receiving obscene amount of traffic or if you suspect someone trying to DOS your server, you can also have both the server and clients sync to request/response on a procedurally generated URL that can change often. It is wasteful to open/close so many HTTPS sessions if someone is just flooding you with requests.

溺渁∝ 2024-07-26 17:54:31

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

如果您没有使用 Ruby on Rails,那么无论您使用什么技术,这种代码身份验证方法都可能是您自己研究和实现的好方法。

请查看 Rails 安全指南,特别是第 3.1 节(CSRF 对策)。

I'm not sure what web technology you are using, but if you are using Ruby on Rails, it uses a secret authentication token in all of its controllers to make sure malicious code isn't accessing destructive methods (via PUSH, POST, or DELETE). You would need to send that authentication token to the server in your request body to allow it to execute. That should achieve what I think you are looking for.

If you're not using Ruby on Rails, that method of code authentication might be a good one to research and implement yourself in whatever technology you are using.

Take a look at the Rails Security Guide, specifically section 3.1 (CSRF Countermeasures).

木槿暧夏七纪年 2024-07-26 17:54:31

您可以执行一些操作,例如加密 iPhone 中的当前时间和 IP 地址,然后在服务器上解密。 缺点是你需要 iPhone 应用程序知道“秘密”密钥,这样只有它才能生成有效的访问令牌……一旦密钥泄露出去,如果你的设备被黑客攻击,它被黑客入侵只是时间问题。应用程序确实值得付出努力。

您可以使用应用程序的某个随机部分(即要使用它的应用程序)来加密响应,并在响应的未加密位中指定二进制文件的位置。 那么至少只有有权访问您的二进制文件的客户端才能解密它......但同样,这也不是 100% 安全的。

最终,您需要问自己,您想要投入多少精力来保护服务,以及您认为黑客会投入多少精力来滥用它。

You could do something like encrypting the current time and IP address from the iPhone, and then decrypt it on the server. The downside is that you need the iPhone app to know the "secret" key so that only it can generate valid access tokens... and once the key is in the wild, it will only be a matter of time before it's hacked if your app is really worth the effort.

You could encrypt the response using some random portion of the application which is meant to be using it, specifying the location of the binary in an unencrypted bit of the response. Then at least only clients with access to your binary would be able to decrypt it... but again, that's hardly 100% secure.

Ultimately you need to ask yourself how much effort you want to put into securing the service vs how much effort you think hackers will put into abusing it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文