title: REST API token authentication
body: <p>I just started a development of my first REST API in .NET. Since it will be stateless I will use tokens for authentication:</p>
  
  <p><strong>Basic idea (System.Security.Cryptography):</strong></p>
  
  <ul>
  <li>AES for encryption + HMACSHA256 for integrity</li>
  <li>token data will consist object with properties: username, date of issuing and timeout</li>
  <li>database will hold username, hashed password and HMAC hash</li>
  </ul>
  
  <p><strong>Login:</strong></p>
  
  <ul>
  <li>check if credentials are valid (username, compare hashed password to db value)</li>
  <li>if true, encrypt data object</li>
  <li>use HMAC on generated token and store it to database</li>
  <li>return token (without HMAC) to user (cookie/string)</li>
  </ul>
  
  <p><strong>Request to method which requires authentication:</strong></p>
  
  <ul>
  <li>user sends token with each request</li>
  <li>token is decrypted</li>
  <li>if it is expired, error</li>
  <li>if not expired use HMAC and compare username + generated hash with db values</li>
  <li>if db check valid, user is authenticated</li>
  </ul>
  
  <p><strong>The way I see it, this approach has following pros:</strong></p>
  
  <ul>
  <li>even if db is comprosmised, it does not contain actual token (hash cannot be reversed...)</li>
  <li>even if attacker has token, he cannot increase expiration by updating fields since expiration date is in the token itself</li>
  </ul>
  
  <p>Now firstly, I wonder if this is good approach at all. </p>
  
  <p>Besides that I still didn't figure out, where to store AES and SHA256 keys on server (should i just hardcode them? If I put them into web.config or use machine key than I have a problem in case of load balanced servers,...).</p>
  
  <p>And lastly where do I store AES IV vectors, since Crypto.CreateEncryptor requires it for decryption? Does it mean that users have to send token + IV with each request?</p>
  
  <p>I hope this makes any sense and I thank you for answers in advance.</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Ok, now I did some more research and came down with this solution:</p>
  
  <ul>
  <li>token will contain originally specified data (username, date of issuing and timeout)</li>
  <li>token is generated with <a href="https://stackoverflow.com/a/10366194/637900">encrypt-then-mac</a> (it includes AES encrypted data, IV vector + tag of these 2 values for authentication, generated with HMACSHA265)</li>
  <li>token tag will be written to db</li>
  <li>user will be authenticated if:
  
  <ul>
  <li>tag is valid (token authentication)</li>
  <li>data can be decrypted</li>
  <li>token has not expired yet</li>
  <li>tag matches the one written in database</li>
  <li>user is not blocked in database (token invalidation on demand)</li>
  </ul></li>
  <li>keys will be stored in web.config separate section. Same keys will have to be on every server (per application of course)</li>
  </ul>
  
  <p>I didn't use FormsAuthenticationTicket because in .NET there are following issues:</p>
  
  <ul>
  <li>same keys are used for different purposes (machinekey for view states, resources and formauthtickets)</li>
  <li>mac-then-encrypt, used by .NET is not considered <a href="https://crypto.stackexchange.com/questions/202/should-we-mac-then-encrypt-or-encrypt-then-mac">as safe as encrypt-then-mac</a></li>
  <li>no built in way to <a href="http://software-security.sans.org/blog/2012/04/05/forms-authentication-remember-me-its-hard-not-too?utm_source=twitterfeed&amp;utm_medium=twitter" rel="nofollow noreferrer">invalidate token before it is expired</a></li>
  </ul>