2

Many API's (services) today use OAuth, HTTP Basic Authentication or API keys to authenticate their users.

My goal is to find a simplistic secure way to authenticate users in a client-side webapplication in a stateless way for one service.

Authentication methods

Here's my view on some of the authentication methods:

  1. OAuth seems like a great solution, but it looks very complicated to setup and seems overkill for just one service.

  2. According to OWASP "HTTP Basic authentication is not secure and should not be used in applications".

  3. Using plain API keys in a client-side webapplication does not seem like an improvement in comparison to HTTP Basic authentication.

Using encrypted tokens

My alternative idea is to use encrypted tokens which can be verified by the service.

  1. The token's plaintext will contain the username, password & the expiration date of the token.
  2. The plaintext will be encrypted using a secret key which is only known by the server.

  3. The plaintext will be encrypted on the server using AES in GCM mode, so that the integrity can't be manipulated.

The user needs to login with his/her username and password to receive a token. This token is send on every request and can be verified on the server.

To illustrate:

+----------+                                          +-----------+
|          +------      Login with user:pass     ---->+           |
|  Client  |                                          |    API    |
|          +<----       Send encrypted token      ----|           |
|          |                                          |           |
|          +------    Use token to authenticate  ---->+           |
+----------+                                          +-----------+

Verification

Verification can be done by:

  1. Decrypt the token using the secret key.
  2. Verify username and password.
  3. Check if the token is expired.

Pro's

Possible pro's of this approach:

  1. Tokens can be stored in localStorage to mitigate against CSRF attacks and users are able to logout by clearing the localStorage.
  2. Plaintext login information is not send on every request.
  3. Tokens can expire.

Cons

Possible cons of this approach:

  1. More load on the server by decrypting every request.
  2. A token is bound to a specific server.

What do you think is a good solution? Do you know other good alternatives?

  • If you use HTTP Basic with SSL for an API doesn't that make the two arguments pointed out by OWASP invalid again? Though it's still less secure because of no expiration logic as with the token – Chris Jun 20 '18 at 16:02
  • just because you can use bold formatting all over doesn't mean you should – Joe Jun 22 '18 at 11:39
5

Your proposed solution is almost identical to JSON Web Tokens (JWT), which are precisely that:

  • A stateless token containing information about the user
  • Signed and/or encrypted using shared secret or asymmetric key
  • Marked with an expiry timestamp

See https://jwt.io/ for more information. You would be very well served using this standard rather than rolling your own, as many well-tested libraries already exist for handling these tokens.

Note that it is generally unnecessary to store the password in the token, since the fact that it was encrypted or signed with your private key proves that it was created by your authentication routine. This gives the important benefit that you can have a completely separate authentication service, which verifies passwords and generates tokens, while your main application only knows how to read the tokens.

Regarding tying things to a particular server, you can handle multiple servers in one of two ways:

  • Use symmetric encryption, with the same shared secret installed on all your servers, but still impossible for anyone else to discover.
  • Use asymmetric encryption, and generate a different private key on each server which needs to create tokens, and deploy the corresponding public keys to each server which needs to read tokens.
  • Thank you for pointing me to JWT. I always thought that JWT was too tightly coupled with oAuth for some reason. Sounds like a great solution. – swordsecurity Jun 20 '18 at 12:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.