4

I'm getting started in app development and I'm thinking about the login flow of first app. Some other apps like Whatsapp and Clash of Clans does not require any sign up or login process in order to connect. So, I tought about this methodology:

  1. If it's the first time launching the app, it will send a "Sign up" event to the server with a username that the user chooses.
  2. The server will check if the username is already in use, and if not, it will create an account in the database with the username and generate a access token of 64 characters long.
  3. The server will send the access token to the client
  4. The client will store the access token for further login requests and it'll be the only way of authentication.

All the connection process would be over TLS to a socket.io server.

Is this safe against a remote or local attacker? What would be the best way of storing the access token locally? Should I encrypt it locally? How should I encrypt? Should I encrypt it in the server database?

2

I work as an IT Security professional (IT Auditor), so can answer from experience.

First, I will define a secure token. In order for the access token to be secure: you would need to satisfy the below:

  1. Token expires at some point
  2. Token cannot be modified in transit between client and server.
  3. User cannot modify the token.

Token expires at some point

This requirement is the easiest. You specify a date when this token will no longer be valid, on the server side. If date of the login > expiration date of the token, then reject the token as having expired.

Token cannot be modified in transit between client and server

As you are using TLS, (hopefully version 1.2 and updating to 1.3 when finalized) this problem should be resolved already. TLS provides confidentiality, ensuring that the access token is not disclosed without authorization to a third party.

User cannot modify the token

This requirement is the most difficult. To accompanist this, you would need to use a digital signature with PKI. Do not use SHA 1 as the hashing function because this algorithm is INSECURE. Applying the hashing function to the access token results in a message digest. The message digest is then encrypted using the private key that only the user knows. Once the credential are decrypted on the server using the public key of the user, if the resulting message matches the credentials on the server, then it is guaranteed that no modification of the access token by the user took place.

The above method guarantees the C - confidentiality, and I - Integrity requirements of the security CIA triad. Non-repudiation (user cannot deny it is his credentials) is also guaranteed due to the public key of the user being able to decrypt the encrypted message received.

To answer some of your other questions:

Should I encrypt the access token locally when stored?

Yes you should. The above pertains to data in transit, but not at rest. If a hacker were to compromise the local client machine, he or she can easily steal a plaintext token, and then impersonate the rightful owner.

How should I encrypt?

You should use a strong encryption algorithm such as AES or RSA. Chose a long key length (ex: 256) to maximize security.

  • 1
    I thought token can't be modified in transit because it is signed with JSON Web Signature. Am I wrong? – defalt Nov 16 '16 at 9:39
  • I think I can't expire the access token since it's the only way to the user get access to his account. The user does not sign up with a password. He only sets his username. – zearthur99 Nov 16 '16 at 11:18
1

Is this safe against a remote or local attacker?

One thing that I can think of is a malicious user replaying the access token to masquerade as the valid client.
To mitigate this, you can use timestamp. Another option could be to get a new access token from the server after every request.

What would be the best way of storing the access token locally? Should I encrypt it locally? How should I encrypt? Should I encrypt it in the server database?

Keeping the access token as an encrypted value in local storage can work. I am not an expert on mobile apps but I believe you have access to a database in mobile apps. You can store the data encrypted over there. At the same time, keeping the token encrypted on the server is also good a good idea.

1

Is this safe against a remote or local attacker?

To accomplish the goals you mention, you really want the token to be encrypted server-side with a server-only key. To make a long story short(er), this is very difficult to do properly as a novice developer.

Doing this correctly requires considering protections against:

  • Malleability - the ability of the user to modify (or extend) the token, whether or not the user can read it. This is typically accomplished with an HMAC.
  • Replay - The ability of the user (or someone else who gets access to the token) to reuse the token in another context. This can be done with expiration dates or more completely with single-use tokens (that are refreshed with each use), with each solution requiring different server-side resources.
  • Brute-force decryptions or correlations - based on attacks such as rainbow tables. These are typically mitigated with salts and peppers/padding.

You also have to worry about rotating the server key regularly, maintaining backward-compatability for the tokens you generated (say for older versions of your app), and updating the underlying cryptographic scheme if there is a compromise (e.g., do you want to revoke all outstanding tokens in this case?).

Final analysis

If you want to cook up your own scheme, I suggest that you collaborate with someone with a solid (and up-to-date) cryptography background. I would recommend a canned solution, but I am not aware of anything that is freely available and really plug-and-play secure.

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.