As usual, it depends on what level of protection you need and how much you are willing to invest. Since you cannot use sessions, you need some kind of stateless method for authentication. Usually there are two ways to do this: send credentials every time (for example, basic authentication) or send some kind of token (BTW, the session identifier is exactly the token that refers to a live session on the server).
When you create a token, it is recommended that you use a standard and proven algorithm instead of inventing your own and / or relying on ambiguity. Even if it looks basically safe, it may not be. For example, there are known attacks against the idea of MD5 above (it is easy to add data to a message without knowing the key and get another valid MAC). HMAC-SHA1 is designed to avoid this.
First of all: if you can, use SSL for all requests. This would do several things at once:
- users (your application) can be sure that they send their data to the right place (i.e. your web address). SSL server authentication will take care of this.
- he will make sure that any accounts / tokens that you publish will be automatically encrypted.
- Repeated attack becomes almost impossible.
It seems that you already have authenticated users, so issuing tokens should be relatively easy. You might want to think about how to implement the protocol, but since you are considering more cases, you will be closer to redeveloping OAuth and friends. Some things to consider:
- validity period on tokens: so even if someone takes possession of them, they cannot use it for an indefinite period.
- token cancellation method
- may have different tokens for different parts (services) of the web application, so you can only provide / revoke access to the necessary services.
To make sure that you (i.e. your webapp (s)) are the only ones who can issue the indicated tokens, you would like to sign them using the key that you have. Since the signer and the verifier are the same (you), you do not need to use public key cryptography, which the HMAC must do. You could, for example, combine username, release time and any other relevant information and use them as input to the HMAC. Pack these parameters together with the signature (HMAC output) to create a token, and the application will send it with each request. Check on the server and allow access if they are valid, require re-login (new token), if they expired, deny access otherwise.
Alternatively, if you want to authenticate only the application, and not enter user information into it, you can use a similar approach for signing requests on the client side (application). If you choose this method, use the standard algorithm. Of course, this will require that the signing key (in some form) be in the application, so if someone takes possession of it (by reverse engineering, etc.), they can issue as many requests as they want. There are ways to mitigate this, though:
- implement signature logic in native code
- Do not store the raw key, but output it at runtime from bits and pieces stored in different places.
And, of course, the easiest way would be to require basic or digest authentication on the server (of course, via SSL) and embed the username and password in the application (quite confusing). On the server side, which requires only server configuration changes, a few lines are added on the client side. The downside is that there really is no way to change these credentials if they are compromised (by not releasing a new version and blocking access from the old one to get people to update, not enough).