I'd like to develop a simple Android application that authorizes access to a server in the following way:
- The app stores a local counter
t_countof access tokens which initializes att_count = X; - Whenever the user wants to access the server, the app signs a proof that it consumed one token and sends it to the server via a local connection;
- Once the machine acknowledges the proof, the app securely decrements the token counter;
- If
t_count = 0, the app should prevent the user from sending consumption proofs.
The most important here is that the app can only decrement the counter, and only with an associated a signed proof of consumption. No other modifications should be allowed, even if the user has root access. Ideally, this counter should be stored in a TEE-protected environment.
While doing some research I discovered Android supports a TEE-backed key storage that prevents attackers from extracting private keys. However, it is unclear to me whether I can use this functionality to store an arbitrary counter or, if not, what would be the best way to protect it. I don't know how I can securely update and verify the counter either (or even if this is possible). I don't have any background in Android development.
Thanks in advance.
EDIT: I cannot place the counter in the server because in my use case the user can access many servers which are offline. Hence, the easiest way to keep track of the accesses is to manage the counter inside the user's device (if it can be done securely).
What you are trying to do is not possible.
You should never trust a client. From the Server's point of view, it is impossible to tell if it is interacting with software that you developed v.s. software that an attacker developed. Relying on a client to not send "consumption proofs" based purely on a counter that the client has control over is not secure. As an aside, if there exists a way for a client to send "consumption proofs" without actually consuming anything, then it is not a proof of consumption.
If you want to limit accesses to a server, it must be enforced on the server side.