保护可从 Android 访问的 REST API

2022-08-30 13:09:48

我们正在为Android构建一个游戏,它需要访问Web服务 - 所以我们用PHP编写了一个在我们自己的服务器上运行的RESTful API。API提供的是:创建用户,登录,下载游戏,检索游戏列表,提交分数等。现在我在想,如果一些有经验的用户获得API的URL格式 - 他/她将能够以多种方式丢弃系统:

  • 创建一个脚本并运行它来创建自动用户 - 我想我可以通过CAPTCHA或类似的东西来防止它。但同样,验证码会惹恼游戏玩家。
  • 恶意用户使用他的浏览器登录,下载游戏,然后按照自己的意愿提交分数 - 所有这些都是通过调用API从浏览器中键入的。我假设恶意用户以某种方式知道要调用的API URL - 通过嗅探应用程序发出HTTP请求的时间。
  • 我需要确保仅从安装游戏的 Android 设备发出请求。(游戏将是免费的)

现在,我该如何防止此类滥用行为?


答案 1

我认为您将永远无法隐藏应用程序调用的URL(如果我运行的是root-ed Android手机,我应该能够监视所有网络流量)

但你真正的问题是你需要以某种方式验证你的api。

一种方法是实现OAUTH,但也许这有点过分了。

如果你想要一个简单的机制,怎么样?

  1. 创建密钥
  2. 构建 api 请求(例如。https://my.example.com/users/23?fields=name,email)
  3. 哈希此请求路径 + 加上您的密钥(例如 md5(url+secret_key) == “a3c2fe167”)
  4. 将此哈希添加到您的请求中(现在 https://.....?fields=name,email&hash=a3c2fe167)
  5. 在 api 端,执行相同的转换(删除哈希参数)
  6. 检查网址的 md5 和密钥

只要秘密仍然是秘密,没有人可以伪造您的请求。

示例(在伪代码中):

安卓端:

SECRET_KEY = "abc123"

def call_api_with_secret(url, params)
  # create the hash to sign the request
  hash = MD5.hash(SECRET_KEY, url, params)

  # call the api with the added hash
  call_api(url+"&hash=#{hash}", params)
end

服务器端:

SECRET_KEY = "abc123"

def receive_from_api(url, params)
  # retrieve the hash
  url_without_hash, received_hash = retrieve_and_remove_hash(url)

  # check the hash
  expected_hash = MD5.hash(SECRET_KEY, url_without_hash, params)

  if (expected_hash != received_hash)
    raise our exception!
  end

  # now do the usual stuff
end

答案 2

其他人在这里提出的解决方案被称为通过晦涩的安全。基本上,他们试图模糊协议并隐藏实现。这可能会起作用,直到有足够能力的人反汇编应用程序并对协议进行逆向工程。黑客在这方面非常有能力。

问题是你的应用是否值得破解?像iTunes,DVD或Sony PS3网络这样的方案显然值得付出努力。如果没有人能够破解护理,那么晦涩的方法可能会起作用。只是不要自欺欺人,认为这是不可行的。

由于您无法信任设备或应用程序,因此必须信任用户。为了信任用户,需要用户识别和授权系统。基本上是登录到您的应用程序。与其滚动你自己的识别系统(使用确认电子邮件登录等),不如使用第三方系统:OpenID(谷歌帐户)或OAuth(Facebook,twitter)。在Facebook的情况下,使用服务器端身份验证方案。

我会做什么:

  1. 允许用户自由玩游戏,直到他们想要将结果“保存”在服务器上。
  2. 在保存结果之前,请让他们通过上述方法登录。
  3. 使用 HTTPS 将数据发送到服务器。从受信任的 CA 购买 SSL 证书,这样您就不必处理自签名证书。

推荐