I'm implementing a REST web service using C# which will be hosted on Azure as a cloud service. Since it is a REST service, it is stateless and therefore no cookies or session states.
The web service can only be accessed over HTTPS (Certificate provided by StartSSL.com).
Upon a user successfully logging into the service they will get a security token. This token will provide authentication in future communications.
The token will contain a timestamp, userid and ip address of the client.
All communication will only happen over HTTPS so I'm not concerned about the token being intercepted and used in replay attacks; the token will have an expiry anyway.
Since this is a public facing service I am however concerned that someone could register with the service, login and then modifying the token that they receive to access the accounts of other users.
I'm wondering how best to secure the content of the token and also verify that it hasn't been tampered with.
I plan on doing the following to secure the token:
The client successfully logs into the service and the service does:
- Generate a random value and hash it with SHA256 1000 times.
- Generate a one-time session key from private key + hashed random value.
- Hash the session key with SHA256 1000 times and then use it to encrypt the token
- Use private key to sign the encrypted token using RSA.
- Sends the encrypted token + the signature + the hashed random value to the client in an unencrypted JSON package.
When the client calls a service it sends the encrypted token and signature in an unencrypted JSON package to the service. The service will
- Recreate the session key from the private key + the hashed random value
- Use the private key to verify the signature
- Use the hashed session key to decrypt the token
- Check that the token hasn't expired
- Continue with the requested operation...
I don't really know anything about encryption so I have some questions:
- Is this sufficient or is it overkill?
- I read that to detect tampering I should include an HMAC with the token. Since I am signing with the private key, do I still need an HMAC?
- Should I be using Rijndael instead of RSA?
- If Rijndael is preferred, is the generated IV required for decrypted? i.e. can i throw it away or do I need to send it will the encrypted token? e.g. Encrypted Token + HMAC + IV + hashed random value.
Since all communication happens over HTTPS the unencrypted JSON package isn't really unencrypted until it reaches the client.
Also I may want to re-implement the service in PHP later so this all needs to be doable in PHP as well.
Thanks for your help