Is there any way to restrict post requests to my REST API only to requests coming from my own mobile app binary? This app will be distributed on Google Play and the Apple App Store so it should be implied that someone will have access to its binary and try to reverse engineer it.
有没有办法限制我的REST API的帖子请求只限于来自我自己的移动应用程序二进制文件的请求?此应用程序将在Google Play和Apple App Store上发布,因此应该暗示有人可以访问其二进制文件并尝试对其进行反向工程。
I was thinking something involving the app signatures, since every published app must be signed somehow, but I can't figure out how to do it in a secure way. Maybe a combination of getting the app signature, plus time-based hashes, plus app-generated key pairs and the good old security though obscurity?
我正在考虑涉及应用程序签名的内容,因为每个已发布的应用程序都必须以某种方式签名,但我无法弄清楚如何以安全的方式执行此操作。也许结合获取应用程序签名,加上基于时间的哈希,加上应用程序生成的密钥对和良好的旧安全性虽然默默无闻?
I'm looking for something as fail proof as possible. The reason why is because I need to deliver data to the app based on data gathered by the phone sensors, and if people can pose as my own app and send data to my api that wasn't processed by my own algorithms, it defeats its purpose.
我正在寻找尽可能失败证明的东西。原因是因为我需要根据手机传感器收集的数据向应用程序提供数据,如果人们可以伪装成我自己的应用程序并将数据发送到我自己的算法未处理的api,它就会失败目的。
I'm open to any effective solution, no matter how complicated. Tin foil hat solutions are greatly appreciated.
无论多么复杂,我都愿意接受任何有效的解决方案。锡箔帽解决方案非常受欢迎。
4 个解决方案
#1
15
Any credentials that are stored in the app can be exposed by the user. In the case of Android, they can completely decompile your app and easily retrieve them.
用户可以公开存储在应用程序中的任何凭据。在Android的情况下,他们可以完全反编译您的应用程序并轻松检索它们。
If the connection to the server does not utilize SSL, they can be easily sniffed off the network.
如果与服务器的连接不使用SSL,则可以轻松地从网络中嗅探它们。
Seriously, anybody who wants the credentials will get them, so don't worry about concealing them. In essence, you have a public API.
说真的,任何想要凭据的人都会得到它们,所以不要担心隐藏它们。实质上,您有一个公共API。
There are some pitfalls and it takes extra time to manage a public API.
存在一些陷阱,管理公共API需要额外的时间。
Many public APIs still track by IP address and implement tarpits to simply slow down requests from any IP address that seems to be abusing the system. This way, legitimate users from the same IP address can still carry on, albeit slower.
许多公共API仍然按IP地址跟踪并实施tarpits,以简单地减慢来自任何似乎滥用系统的IP地址的请求。这样,来自同一IP地址的合法用户仍然可以继续,尽管速度较慢。
You have to be willing to shut off an IP address or IP address range despite the fact that you may be blocking innocent and upstanding users at the same time as the abusers. If your application is free, it may give you more freedom since there is no expected level of service and no contract, but you may want to guard yourself with a legal agreement.
您必须愿意关闭IP地址或IP地址范围,尽管您可能在滥用者的同时阻止无辜和正直的用户。如果您的申请是免费的,它可能会给您更多的*,因为没有预期的服务水平和合同,但您可能希望通过法律协议来保护自己。
In general, if your service is popular enough that someone wants to attack it, that's usually a good sign, so don't worry about it too much early on, but do stay ahead of it. You don't want the reason for your app's failure to be because users got tired of waiting on a slow server.
一般来说,如果你的服务很受欢迎,有人想攻击它,那通常是一个好兆头,所以不要过早担心它,但要保持领先。您不希望应用程序失败的原因是因为用户厌倦了在慢速服务器上等待。
Your other option is to have the users register, so you can block by credentials rather than IP address when you spot abuse.
您的另一个选择是让用户注册,因此当您发现滥用行为时,您可以通过凭据而不是IP地址进行阻止。
#2
7
No. You're publishing a service with a public interface and your app will presumably only communicate via this REST API. Anything that your app can send, anyone else can send also. This means that the only way to secure access would be to authenticate in some way, i.e. keep a secret. However, you are also publishing your apps. This means that any secret in your app is essentially being given out also. You can't have it both ways; you can't expect to both give out your secret and keep it secret.
不。您正在发布具有公共界面的服务,您的应用程序可能只通过此REST API进行通信。您的应用可以发送的任何内容,其他人也可以发送。这意味着保护访问的唯一方法是以某种方式进行身份验证,即保密。但是,您也在发布您的应用。这意味着您的应用程序中的任何秘密基本上也被发出。你无法双管齐下;你不能指望两者都透露你的秘密并保守秘密。
#3
1
there is nothing much you can do. cause when you let some one in they can call your APIs. the most you can do is as below:
你无能为力。因为当你让一些人可以调用你的API时。你能做的最多就是:
since you want only and only your application (with a specific package name and signature) calls your APIs, you can get the signature key of your apk pragmatically and send is to sever in every API call and if thats ok you response to the request. (or you can have a token API that your app calls it every beginning of the app and then use that token for other APIs - though token must be invalidated after some hours of not working with)
因为你只想要你的应用程序(具有特定的包名和签名)来调用你的API,你可以实际获得apk的签名密钥,并在每次API调用中发送到服务器,如果可以,你就可以响应请求。 (或者您可以拥有一个令牌API,您的应用程序会在应用程序的每个开头调用它,然后将该令牌用于其他API - 尽管令牌必须在几个小时不使用后失效)
then you need to proguard your code so no one sees what you are sending and how you encrypt them. if you do a good encrypt decompiling will be so damn hard to do.
然后你需要预测你的代码,这样就没有人能看到你发送的内容以及你如何加密它们。如果你做一个很好的加密反编译将是如此该死的。
even signature of apk can be mocked in some hard ways but its the best you can do.
甚至apk的签名都可以用一些艰难的方式来嘲笑,但它是你能做的最好的。
#4
0
As the other answers and comments imply, you cant truly restrict API access to only your app but you can take different measures to reduce the attempts. I believe the best solution is to make requests to your API (from native code of course) with a custom header like "App-Version-Key" (this key will be decided at compile time) and make your server check for this key to decide if it should accept or reject. Also when using this method you SHOULD use HTTPS/SSL as this will reduce the risk of people seeing your key by viewing the request on the network.
正如其他答案和评论所暗示的那样,您无法真正限制API访问仅限您的应用,但您可以采取不同的措施来减少尝试。我相信最好的解决方案是使用自定义标头(例如“App-Version-Key”)向您的API发出请求(来自本机代码)(此密钥将在编译时决定)并让您的服务器检查此密钥决定是否接受或拒绝。此外,在使用此方法时,您应该使用HTTPS / SSL,因为这样可以通过查看网络上的请求来降低人们查看密钥的风险。
Regarding Cordova/Phonegap apps, I will be creating a plugin to do the above mentioned method. I will update this comment when its complete.
关于Cordova / Phonegap应用程序,我将创建一个插件来执行上述方法。完成后我会更新此评论。
#1
15
Any credentials that are stored in the app can be exposed by the user. In the case of Android, they can completely decompile your app and easily retrieve them.
用户可以公开存储在应用程序中的任何凭据。在Android的情况下,他们可以完全反编译您的应用程序并轻松检索它们。
If the connection to the server does not utilize SSL, they can be easily sniffed off the network.
如果与服务器的连接不使用SSL,则可以轻松地从网络中嗅探它们。
Seriously, anybody who wants the credentials will get them, so don't worry about concealing them. In essence, you have a public API.
说真的,任何想要凭据的人都会得到它们,所以不要担心隐藏它们。实质上,您有一个公共API。
There are some pitfalls and it takes extra time to manage a public API.
存在一些陷阱,管理公共API需要额外的时间。
Many public APIs still track by IP address and implement tarpits to simply slow down requests from any IP address that seems to be abusing the system. This way, legitimate users from the same IP address can still carry on, albeit slower.
许多公共API仍然按IP地址跟踪并实施tarpits,以简单地减慢来自任何似乎滥用系统的IP地址的请求。这样,来自同一IP地址的合法用户仍然可以继续,尽管速度较慢。
You have to be willing to shut off an IP address or IP address range despite the fact that you may be blocking innocent and upstanding users at the same time as the abusers. If your application is free, it may give you more freedom since there is no expected level of service and no contract, but you may want to guard yourself with a legal agreement.
您必须愿意关闭IP地址或IP地址范围,尽管您可能在滥用者的同时阻止无辜和正直的用户。如果您的申请是免费的,它可能会给您更多的*,因为没有预期的服务水平和合同,但您可能希望通过法律协议来保护自己。
In general, if your service is popular enough that someone wants to attack it, that's usually a good sign, so don't worry about it too much early on, but do stay ahead of it. You don't want the reason for your app's failure to be because users got tired of waiting on a slow server.
一般来说,如果你的服务很受欢迎,有人想攻击它,那通常是一个好兆头,所以不要过早担心它,但要保持领先。您不希望应用程序失败的原因是因为用户厌倦了在慢速服务器上等待。
Your other option is to have the users register, so you can block by credentials rather than IP address when you spot abuse.
您的另一个选择是让用户注册,因此当您发现滥用行为时,您可以通过凭据而不是IP地址进行阻止。
#2
7
No. You're publishing a service with a public interface and your app will presumably only communicate via this REST API. Anything that your app can send, anyone else can send also. This means that the only way to secure access would be to authenticate in some way, i.e. keep a secret. However, you are also publishing your apps. This means that any secret in your app is essentially being given out also. You can't have it both ways; you can't expect to both give out your secret and keep it secret.
不。您正在发布具有公共界面的服务,您的应用程序可能只通过此REST API进行通信。您的应用可以发送的任何内容,其他人也可以发送。这意味着保护访问的唯一方法是以某种方式进行身份验证,即保密。但是,您也在发布您的应用。这意味着您的应用程序中的任何秘密基本上也被发出。你无法双管齐下;你不能指望两者都透露你的秘密并保守秘密。
#3
1
there is nothing much you can do. cause when you let some one in they can call your APIs. the most you can do is as below:
你无能为力。因为当你让一些人可以调用你的API时。你能做的最多就是:
since you want only and only your application (with a specific package name and signature) calls your APIs, you can get the signature key of your apk pragmatically and send is to sever in every API call and if thats ok you response to the request. (or you can have a token API that your app calls it every beginning of the app and then use that token for other APIs - though token must be invalidated after some hours of not working with)
因为你只想要你的应用程序(具有特定的包名和签名)来调用你的API,你可以实际获得apk的签名密钥,并在每次API调用中发送到服务器,如果可以,你就可以响应请求。 (或者您可以拥有一个令牌API,您的应用程序会在应用程序的每个开头调用它,然后将该令牌用于其他API - 尽管令牌必须在几个小时不使用后失效)
then you need to proguard your code so no one sees what you are sending and how you encrypt them. if you do a good encrypt decompiling will be so damn hard to do.
然后你需要预测你的代码,这样就没有人能看到你发送的内容以及你如何加密它们。如果你做一个很好的加密反编译将是如此该死的。
even signature of apk can be mocked in some hard ways but its the best you can do.
甚至apk的签名都可以用一些艰难的方式来嘲笑,但它是你能做的最好的。
#4
0
As the other answers and comments imply, you cant truly restrict API access to only your app but you can take different measures to reduce the attempts. I believe the best solution is to make requests to your API (from native code of course) with a custom header like "App-Version-Key" (this key will be decided at compile time) and make your server check for this key to decide if it should accept or reject. Also when using this method you SHOULD use HTTPS/SSL as this will reduce the risk of people seeing your key by viewing the request on the network.
正如其他答案和评论所暗示的那样,您无法真正限制API访问仅限您的应用,但您可以采取不同的措施来减少尝试。我相信最好的解决方案是使用自定义标头(例如“App-Version-Key”)向您的API发出请求(来自本机代码)(此密钥将在编译时决定)并让您的服务器检查此密钥决定是否接受或拒绝。此外,在使用此方法时,您应该使用HTTPS / SSL,因为这样可以通过查看网络上的请求来降低人们查看密钥的风险。
Regarding Cordova/Phonegap apps, I will be creating a plugin to do the above mentioned method. I will update this comment when its complete.
关于Cordova / Phonegap应用程序,我将创建一个插件来执行上述方法。完成后我会更新此评论。