You can deploy mutually authenticated SSL between your legitimate clients and your API. Create a self-signed SSL client certificate and save it in your client. Configure a server that requires client-side verification and accept only the certificates that you deployed for your clients. If someone / something is trying to connect, does not have this client certificate, he will not be able to establish an SSL session, and the connection will fail. Assuming that you control legitimate clients and servers, you do not need a CA certificate here; just use self-signed certificates as you control trust in the client side and the server side.
Now you cause it to be very difficult to prevent the reverse engineering of your client and the restoration of your credentials (in this case, the private key that belongs to the client’s certificate). And you are right. Usually you store this key (and certificate) in sometype key store (a KeyStore
if you use Android), and this key store will be encrypted. This encryption is based on a password, so you need to either (1) save this password in your client somewhere, or (2) ask the user for a password when starting your client application. What you need to do depends on your use. If (2) is acceptable, then you protected your credentials from reverse engineering, as it will be encrypted and the password will not be stored anywhere (but the user will need to enter it every time). If you do this (1), then someone will be able to reverse engineer your client, get a password, get a key store, decrypt the private key and certificate, and create another client that can connect to the server.
There is nothing that could be done to prevent this; you can make reverse engineering your code harder (by obfuscating, etc.), but you cannot make it impossible. You need to determine what risk you are trying to mitigate with these approaches, and how much work it takes to mitigate it.
source share