title: REST Web Service authentication token implementation
body: <p>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.  </p>
  
  <p>The web service can only be accessed over HTTPS (Certificate provided by StartSSL.com).</p>
  
  <p>Upon a user successfully logging into the service they will get a security token.  This token will provide authentication in future communications.</p>
  
  <p>The token will contain a timestamp, userid and ip address of the client.</p>
  
  <p>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.</p>
  
  <p>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.</p>
  
  <p>I'm wondering how best to secure the content of the token and also verify that it hasn't been tampered with.</p>
  
  <p>I plan on doing the following to secure the token:</p>
  
  <p>The client successfully logs into the service and the service does: </p>
  
  <ol>
  <li>Generate a random value and hash it with SHA256 1000 times.</li>
  <li>Generate a one-time session key from private key + hashed random value.</li>
  <li>Hash the session key with SHA256 1000 times and then use it to encrypt the token</li>
  <li>Use private key to sign the encrypted token using RSA.</li>
  <li>Sends the encrypted token + the signature + the hashed random value to the client in an unencrypted JSON package.</li>
  </ol>
  
  <p>When the client calls a service it sends the encrypted token and signature in an unencrypted JSON package to the service.  The service will </p>
  
  <ol>
  <li>Recreate the session key from the private key + the hashed random value </li>
  <li>Use the private key to verify the signature </li>
  <li>Use the hashed session key to decrypt the token</li>
  <li>Check that the token hasn't expired </li>
  <li>Continue with the requested operation...</li>
  </ol>
  
  <p>I don't really know anything about encryption so I have some questions:</p>
  
  <ol>
  <li>Is this sufficient or is it overkill?</li>
  <li>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?</li>
  <li>Should I be using Rijndael instead of RSA?</li>
  <li>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.</li>
  </ol>
  
  <p>Since all communication happens over HTTPS the unencrypted JSON package isn't really unencrypted until it reaches the client.</p>
  
  <p>Also I may want to re-implement the service in PHP later so this all needs to be doable in PHP as well.</p>
  
  <p>Thanks for your help</p>