Secure Yet Simple Authentication System for Mobile Applications
Shared Secret Based Hash Authentication
Before I explain this, let me first define what authentication actually is, and more importantly, what it’s not.
Authentication is when a user proves his identity. In other words, Authentication proves that you are what you say you are. It can be considered as an identification card – an item given by a trusted authority that the requester can use as evidence to prove his identity. Authentication doesn’t mean to prove a right to access something rather it is just about recognizing a user.
For apps that require a server-side implementation, needs their users to prove their identity to the server before accessing services, requires authentication. After login, every action must be authenticated in such apps.There are so many ways to authenticate a user request in mobile apps.
In this method, username and password are used for login. This method is not suitable for mobile apps, because it cannot store the credentials safely, and users will not want to enter credentials for every request.
2. Session Based Authentication -
In this method, client authenticates with its credentials and receives a session Id and attaches this to every subsequent outgoing request. Native mobile apps will find session based auth painful. Mobile apps do not automatically maintain and send session cookies. Hence it would be far easier for a mobile app developer to set an authentication token as opposed to setting a session cookie. Avoid session based auth if mobile apps are expected to use API.
3. Token Based Authentication -
In this method, it creates a random token during first login, and use that token for all upcoming request. It is passed explicitly with every request as request header. The token can also expires after a set amount of time, so a user will be required to login once again. This helps us stay secure. But there's also a little possibility if hacker intercept the request and get the token, then token can be compromised.
4. JWT (JSON Web Tokens) -
In this type of authentication, no session is persisted server-side. A single secret key is used to sign or encrypt user info (which primarily includes user id) in an encoded json string. Now an encryption of data with the key, generates the token that is sent to the client and used in every request. Every time, the client sends in the request with the token the server tries to decrypt it with the Key, if it can, it gets the user-id from the JSON Data which corresponds to the user.
Some limitation of this method is -
Compromised Secret Key -The best and the worst thing about JWT is that it relies on just one Key,the whole system will be compromised if it gets leaked !
Cannot manage client from the server-There is no any predefined way to manage user from server. Like there is a case in which we want the users to logout from the system, then directly it is not possible.
Mobile app users expect to login just once, and don't ever login again. JWT with a long expiry can work, but a better strategy is to use a secure random token with no information in it.
In this method, client/mobile app authenticates user with its credentials and receives a secret in response.
This secret is also stored in DB with the user record on server. In app, secret would be stored and used for generating hash and this hash would be passed with each request.
For every request, hash would be different because app creates hash using user’s mobile number, current timestamp and stored secret.The request contains payload, hash, mobile number and current timestamp. Server then gets the associated secret for given mobile number and tries to generate hash with this secret, mobile number and request timestamp to validate the identity of user. Both server and client use single hashing algorithm for generating hash.
I used this method for adding authentication in my mobile app.
Before you actually get to implementing it, keep these best practices in your mind -
Keep the secret encrypted - The secret should be stored safely in your database. You can also store the encrypted secret in database. Apply decryption whenever authenticating any request. Keeping it encrypted can safeguard you against sql injection attack.
Do not add sensitive data to the payload - Hash is just to prove the user’s identity. Add the bare minimum number of claims to the payload for best performance and security.
Change the secret - Changing the secret with every login extends the security and it also adds limit on active sessions of a user with same mobile number.
Embrace HTTPS- Do not share secret over non-HTTPS connections as those requests can be intercepted.
On multiple failed OTP authentication generate a new OTP, do not let user keep trying the OTP unlimited times
Allow user to resend OTP after certain timeout, SMS service is unpredictable
Sometimes OTP delays and they can be delivered in non-linear fashion, so you should alway share first digit on verification screen, so customer can validate which OTP to utilise.
OTP should be easy to punch, should be numeric, and should contain 4 or 6 characters
While storing the secret on client side, you should encrypt it with some key in your source code. This way, if client storage is compromised you can still be safe and have time to respond the compromise.
On client side you can encrypt shared secret by a user selected PIN, so only he can unlock the secret.
Client APP should handle Invalidated Shared Secret by server.
Your server can utilise client geo-location to ask for re-login if user is trying to login from a significantly-different geo-location
This is all about the simple and secure authentication system I used for my mobile apps. Try it for your next mobile app and share your experience.
Let me know, what secure and simple authentication method you use.