How to verify that server calls are being made from the app? - php

I have an android app that needs to connect frequently to the server to retrive or add in the database sensible data. I needed to verify that the calls to the server where being made from the app so I used this approach: how to verify the identity of the client from the server? which consists in a hardcoded string key in the app that's verified in the server.
But then I realized that there were tools like dex2jar, that would reveal all my code (Even with some obfuscation from proguard) in particular this hardcoded key.
Is there any more elegant and safe way to verify that the server calls are being made from my app?
PS: I'm sorry for the English, clearly I'm not a native speaker.

If it's only your client and your server, you can (and should) use mutually-authenticated SSL without purchasing anything. You control the server and the client, so each should only trust one certificate, the one belonging to the other and you don't need CAs for this purpose.
Here's the high-level approach. Create a self-signed server SSL certificate and deploy on your web server. You can use the keytool included with the Android SDK for this purpose. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource (keytool will generate this as well). Configure the server to require client-side SSL authentication and to only accept the client certificate you generated. Configure the client to use that client-side certificate to identify itself and only accept the one server-side certificate you installed on your server for that part of it.
A step-by-step for this is a much longer answer than is warranted here. I would suggest doing this in stages as there are resources on the web about how to deal with self-signed SSL certificate in Android, both server and client side. There is also a complete walk-through in my book, Application Security for the Android Platform, published by O'Reilly.
You'll normally store that certificate/private-key in a keystore of sometype (a KeyStore if you're using Android) and that keystore will be encrypted. That encryption is based on a password, so you'll either need to (1) store that password in your client somewhere, or (2) ask the user for the password when they start your client app. What you need to do depends on your usecase. If (2) is acceptable, then you've protected your credential against reverse engineering since it will be encrypted and the password will not be stored anywhere (but the user will need to type it in everytime). If you do (1), then someone will be able to reverse engineer your client, get the password, get the keystore, decrypt the private key and certificate, and create another client that will be able to connect to the server.
There is nothing you can do to prevent this; you can make reverse engineering your code harder (by obfuscation, etc) but you cannot make it impossible. You need to determine what the risk you are trying to mitigate with these approaches is and how much work is worth doing to mitigate it.

Related

Simple method of securing by php API [duplicate]

I have an iPhone app that is using my php api on the server but it is currently open if someone knows the url. I want to make sure that no one can use this API until I am ready to make it a public api (if I even do)
I have read this article but I am unsure what they mean when they say:
[CLIENT] Before making the REST API call, combine a bunch of unique data together (this is typically all the parameters and values you intend on sending, it is the “data” argument in the code snippets on AWS’s site)
I don't understand how if I hash the parameters I plan on sending with my api secret how this is more secure than just hashing the api secret if I send the parameters/values unencrypted.
HTTPS the API and use an API key. Then you'll know that only people (you in this case) with the key can have access to the API.
You're correct about it not being more secure. That's why I suggest you SSL the connection. Unless you plan on encrypting everything you transmit back and forth.
The public/private key scenario will also work well. HTTPS requires very minimal effort.
Digital signatures provide a way of validating a message sent over an insecure connection.
Setup: each client will have its own private key and public key (only the private key needs to be stored on the client). The server will store the public keys for each client. The public key can be visible to all and can be used by the server to identify the client. The private key, known only to the client, it is never shown to anyone.
The client signs the request: along with the rest of the request data, the client will hash the combined request data and encrypt the hash with the private key. The server will generate the hash the same way (leaving the signature out of the hash calculation), then decrypt the signature using the public key. If the hashes match, the request is authentic.
Note that HTTPS allows for client certificates, so you can leverage existing tools to accomplish all of the above without writing a single line of server-side code (you just have to configure your web server; the only trick is to make sure the server only accepts certificates it already has). Moreover, the amount of client side code should be minimal: you shouldn't need to do much more than set the connection to use the client certificate. Since you're controlling the clients, you can use self-signed certificates and add the server as a certificate authority. There are a number of questions on SO about using client certificates in iPhone apps; you can start by reading through them.
Note also that any scheme to protect the web API only works so long as copies of the app are in trusted hands. Should anyone untrustworthy get ahold of it, they can use the app or extract any secret data used by the app and access the API as they will.
For development purposes you can just use your web server settings to allow requests from your ip only.

Application setup similar to REST [duplicate]

I know that there are many similar questions posted, but none of them refers to an HTML/javascript app where the user can access the code.
I have a private REST API written in nodejs. It is private because its only purpose is to server my HTML5 clients apps (Chrome app and Adobe Air app). So an API key is not a good solution since any user can see the javascript code.
I want to avoid bots creating accounts on my server and consuming my resources.
Is there any way to acomplish this?
An API key is a decent solution especially if you require constraints on the API key's request origin; consider that you should only accept an API key if the originating web request comes from an authorized source, such as your private domain. If a web request comes from an unauthorized domain, you could simply deny processing the request.
You can improve the security of this mechanism by utilizing a specialized encoding scheme, such as a hash-based message authentication code (HMAC). The following resource explains this mechanism clearly:
http://cloud.dzone.com/news/using-api-keys-effectively
What you want to do is employ mutually-authenticated SSL, so that your server will only accept incoming connections from your app and your app will only communicate with your server.
Here's the high-level approach. Create a self-signed server SSL certificate and deploy on your web server. If you're using Android, you can use the keytool included with the Android SDK for this purpose; if you're using another app platform, similar tools exist for them as well. Then create a self-signed client and deploy that within your application in a custom keystore included in your application as a resource (keytool will generate this as well). Configure the server to require client-side SSL authentication and to only accept the client certificate you generated. Configure the client to use that client-side certificate to identify itself and only accept the one server-side certificate you installed on your server for that part of it.
If someone/something other than your app attempts to connect to your server, the SSL connection will not be created, as the server will reject incoming SSL connections that do not present the client certificate that you have included in your app.
A step-by-step for this is a much longer answer than is warranted here. I would suggest doing this in stages as there are resources on the web about how to deal with self-signed SSL certificate in Android (I'm not as familiar with how to do this on other mobile platforms), both server and client side. There is also a complete walk-through in my book, Application Security for the Android Platform, published by O'Reilly.

Securing a PHP webservice for application access only

First of all, a better question would be is this possible? My gut instinct is that it isn't entirely, but there may be some clever ways. Even if they just act as a deterrent, make it slightly harder for some one to hack, or even make it easier for me to detect suspicious activity.
Basically, I'm building a web service using PHP for my C#.NET program to connect to. Among other things, one of the most important purpose the web service serves is verifying license data. The program sends the licence key entered by the user to be checked, and if it is valid the web service will return the Name of the person who purchased the licence key so that the program knows to activate itself.
I am fully aware that there is no perfect anti-piracy scheme and that is my software will be cracked if people want it bad enough. However, I do not believe that there isn't anything I can do to make it very hard for people to crack my software.
I do have an SSL certificate so the program will be communicating with the web service using HTTPS, however that's the only security I have at the moment. I have thought about
Using long and obscure names so that the functions are hard to guess
Using MD5 to disguise the functions
Adding a username and password
Checking the User-Agent
etc.
However, I have read that there are applications available to simply extract strings from programs, which would render those measures completely ineffective. Still, I don't know how technical users have to be to use those applications. Is it still worth adding some of these measures to stop casual piracy? Which measures are the better ones and what will be the most effective?
Thanks in advance
You can distribute your C# application with a certificate bundled and sign your requests with the certificate. The server can then verify if the request was signed by your application and reject any other request.
Edit: Whoops, I only now understood that you want to secure you application even when in the hands of a malicious user. This, I don't think is possible. A hacker can decompile, scan the memory, read and decode files, etc and your certificate will be available in there if you distribute it with the application. An alternative would be to distribute an external security token (hardware device or flash storage) which will need to be plugged-in to the client computer. The token holds the certificate, keys or cyphers used to sign/encrypt your requests and it therefore doesn't stay with the application.
Your server-side SSL certificate will only guarantee that the communication channel is secure and the server is not lying about his identity. It doesn't guarantee anything about the client connecting. To also be sure that the client is identified, you need to use a form of client certificate that your server recognises.

Securing access to PHP API

I have an iPhone app that is using my php api on the server but it is currently open if someone knows the url. I want to make sure that no one can use this API until I am ready to make it a public api (if I even do)
I have read this article but I am unsure what they mean when they say:
[CLIENT] Before making the REST API call, combine a bunch of unique data together (this is typically all the parameters and values you intend on sending, it is the “data” argument in the code snippets on AWS’s site)
I don't understand how if I hash the parameters I plan on sending with my api secret how this is more secure than just hashing the api secret if I send the parameters/values unencrypted.
HTTPS the API and use an API key. Then you'll know that only people (you in this case) with the key can have access to the API.
You're correct about it not being more secure. That's why I suggest you SSL the connection. Unless you plan on encrypting everything you transmit back and forth.
The public/private key scenario will also work well. HTTPS requires very minimal effort.
Digital signatures provide a way of validating a message sent over an insecure connection.
Setup: each client will have its own private key and public key (only the private key needs to be stored on the client). The server will store the public keys for each client. The public key can be visible to all and can be used by the server to identify the client. The private key, known only to the client, it is never shown to anyone.
The client signs the request: along with the rest of the request data, the client will hash the combined request data and encrypt the hash with the private key. The server will generate the hash the same way (leaving the signature out of the hash calculation), then decrypt the signature using the public key. If the hashes match, the request is authentic.
Note that HTTPS allows for client certificates, so you can leverage existing tools to accomplish all of the above without writing a single line of server-side code (you just have to configure your web server; the only trick is to make sure the server only accepts certificates it already has). Moreover, the amount of client side code should be minimal: you shouldn't need to do much more than set the connection to use the client certificate. Since you're controlling the clients, you can use self-signed certificates and add the server as a certificate authority. There are a number of questions on SO about using client certificates in iPhone apps; you can start by reading through them.
Note also that any scheme to protect the web API only works so long as copies of the app are in trusted hands. Should anyone untrustworthy get ahold of it, they can use the app or extract any secret data used by the app and access the API as they will.
For development purposes you can just use your web server settings to allow requests from your ip only.

Encryption of data between Mac application and PHP application

I am new to the whole encryption world, and I wish to build a Mac application which interacts with a PHP application in order to access and manipulate data remotely.
My problem is that I can't just transfer plain data over the internet, as most of the data being transfered can be very private, as well as username and password are passed for authentication of the user.
I would like to know what kind of encryption/decryption methods I need to use in order the data will be transfered safely over the internet.
Shillo.
The easiest thing to use is SSL with HTTPS. This is well supported by just about any system and HTTP library. No additional encryption is typically necessary.
To do this, you simply need to purchase an SSL certificate and install it on your web server. You can generate one on your own for free, but a certificate authenticated by a 3rd party is often preferred.

Categories