Verify that a message comes from a specific application / endpoint

I am trying to create a secure system for transferring data from an Android client application to a web server running PHP.

What I want to do is make sure that the system is cryptographically protected so that messages from the application can be checked as actually by the application itself, and not because the user can write a non-standard script or, possibly, using cURL to play in the system.

There are several uses for this type of validation, for example: -

  • If the application contains ads from which you collect indicators, you will need to check that the click data is sent from the application, and not from the malicious user who has found out your API and sends fictitious data.

  • An application can have a survey with several choices and again, you want to make sure that the results of the survey are collected from the application.

  • The application collects GPS tracks, and you want to make sure that the data is sent from the application itself.

In each of these cases, you want to make sure that the message source is the application itself, and not just the user who runs a simple script to fake data.

Some ideas I reviewed: -

  • SSL - works well to ensure channel security and prevent unauthorized access (which satisfies some requirements), but cannot guarantee the integrity of the data source.

  • Public key cryptography . The client application can encrypt data using the private key, and then transfer it to the server, where it can be decoded. The problem is that the private key must be hardcoded in the application - the application can be decompiled and the private key extracted, and then used to send fake data.

  • Home Algorithms . A very similar question to this question is proposed here , where solutions work only until someone shows outside your algorithm "- that is, not a great solution!

  • Hash chain . This seemed like a really interesting way to use one-time keys to check every payload of data from the client to the server, but again relies on the application itself, which does not decompile, because the password still needs to be saved by the application.

My limited knowledge of cryptography makes me think that it is theoretically impossible to build a system that is fully verifiable in this way, because if we cannot trust the end customer or the channel, then there is nothing based on trust ... but maybe there is something i forgot!

+4
source share
1 answer

It is not so difficult, you just need to authenticate the application. You can do this with a simple user and password (via SSL) or use client authentication. In both cases, the credentials must be in the application, and an attacker can extract them and impersonate the application. You should go away with him and perhaps implement some methods to mitigate it.

You can also authenticate messages by signing them with an asymmetric key (RSA, etc.) or symmetric (HMAC, etc.). The nonce function helps against retries when someone captures correctly signed messages and sends them to your server again and again. Depending on your protocol, the overhead of using one may be too much.

To protect the credentials, you can force them to generate them and save them in the KeyStore system, although this is not entirely supported by the public API, see here for some details. This, of course, requires an additional step in which you need to securely send the generated credentials (for example, a public key) to your server, which can be difficult to implement correctly.

Whatever you do, do not try to invent your own cryptographic algorithm or protocol, use the installed one.

0
source

All Articles