在我的Android应用程序中,用户可以向数据库提交内容,然后所有其他用户也可以看到。
此新内容通过GET请求发送到服务器:
http://www.example.org/API.php?newContent=helloWorld
问题是:如果用户发现此URL的外观,他可以轻松地在其浏览器中发送恶意请求并绕过Android应用程序。也许有人可以反编译应用程序并找出URL。
如何保护对此网址的访问并阻止用户直接访问此API?
在应用程序中生成散列并将其与服务器上API.php文件中生成的散列进行比较是否是一个很好的解决方案?
无法找出在反编译应用程序时如何生成哈希?
非常感谢你!
答案 0 :(得分:17)
因此,真正保护该URL的唯一方法是要求对所有请求进行身份验证。
执行此操作的一种方法是将请求更改为POST请求,并使用某种身份验证令牌(简单哈希将执行此操作)与请求一起发送。如果auth令牌不存在,则只是不响应请求。哈希将是你硬编码到客户端和服务器的东西。
现在问题是如何隐藏身份验证令牌。只要您不开源代码,有人获取代码的唯一方法就是按照您的提及反编译您的程序。为了防范这种情况,您可能需要考虑使用proguard(http://developer.android.com/guide/developing/tools/proguard.html)。
需要记住的是,此方法包含单点故障。如果您的身份验证令牌被曝光,您就完成了(例如HD DVD AACS加密密钥崩溃)。
另一种进行身份验证的方法是基于每个用户。只要有效用户发出请求,您就不应该关心请求是来自Web浏览器还是Android应用程序。我认为这是一种更好的做事方式。通过这样做,您可以基于每个用户限制请求。但是,这需要您管理用户配置文件以及随之附带的整个蠕虫病毒。
所有这一切都说,虽然你不应该真的在乎是否有人知道你的部分API的网址。我不知道您的特定用例,但必须有一种设计API的方法,这样您就不会关心如何获取请求。此外,如果您正在进行真正的GET,那么您不应该更改服务器上的任何内容。这意味着所有'恶意人'可以做的就是从中获取数据。这严重限制了他们可以造成的伤害。事实上,除非您拥有不希望某些人查看的敏感数据,否则您根本不会遇到任何问题。如果你这样做,那么你应该考虑我的每用户身份验证解决方案。
答案 1 :(得分:2)
不要相信客户端进行验证。如果它在网络浏览器中的javascript或甚至像Iphone这样的锁定平台都是如此。
如果应用程序可以进行API调用,那么显然所有进行这些调用所需的东西都在手机上(秘密,哈希函数,API密钥等),然后有人可以随时转储手机存储并获取所有数据。然后他们可以提出他们想要的任何要求。
您要做的是验证用户身份,然后验证服务器端的输入。
答案 2 :(得分:2)
使用SSL(HTTPS)进行数据传输。在发送任何数据之前对交换进行加密,因此任何收听的人都将无法看到发送到服务器的URL或数据。要自己验证,请在您的开发系统上安装Wireshark并将URL加载到浏览器中。您将看不到任何明确的数据(URL或通过GET或POST发送的数据)。
答案 3 :(得分:0)
您可以使用一种有点混乱的java方法来混淆URL的每个字母。所以创建自己的字典的方式可能会使URL可能显示为123.3 * 15 * 13或类似的东西如果有人反编译APK,他们就不知道了。在这方面,你最好使用Proguard对其进行模糊处理,因此对于试图进行逆向工程的人来说,你的混淆是没有意义的。
你可以制作一个这样的简短java方法:
public String confuseString() {
Stringbuilder sb = new StringBuilder();
//your real URL would be abc.com, but in the app you have myURL = 123.3*15*13
//With what I'm saying the * would precede a 2 digit number that represents 1 letter
for (int i = 0; i < stringLength; i++){
String letter = myURL.charAt(i);
if (letter.equals("1"){
letter = a;
sb.append(letter);
} // you would go one to code each character into a letter
}
}
当然会有更多if语句,但它允许您在不进行任何服务器端更改的情况下对您的URL进行模糊处理。如果您使用Proguard,那么您创建的整个方法对于尝试进行逆向工程的人来说绝对毫无意义。
你当然可以使你的混淆比我建议的复杂得多,但无论如何这都是一个想法。
基本上你会以一种非常混乱的方式加密URL。
这是一个答案,它可能是一种更好的加密方法,或者至少可以提供额外的加密:
Java - encrypt / decrypt user name and password from a configuration file