Mobile Security via Flutter — Ep.3 Secure API (Part 1/2)

Amorn Apichattanakul
KBTG Life
Published in
6 min readMay 12, 2021

In the last article, I talked about how to strengthen the outer shell of your app with a stronger pin. Now it’s time for how to make your inner shell stronger. We’re talking about secure API.

Since secure API is a long story, I decide to split this episode into 2 parts. The first one we will discuss the concept and the things we have to look out for. The latter, which will be the next article, is how to implement it via Flutter.

Here’s the checklist that you need to implement before securing the API for backend, including the process to make your system stronger, which I will expand more in some cases.

Mandatory

1. Use SSL certificate and accept only HTTPS

2. Use TLS 1.2 or above since 1.0, 1.1 is deprecated (ref)

3. Use a unique userID, don’t use one from a database such as a serial number. For example, don’t do this…

userID = 1 

but do this instead…

userID = C72E77A3D892BA02F2214E3F10

Otherwise, hackers can just run numbers to gain useful information.

4. Lock the user out if they put the password/pin wrong X times. X depends on your business requirements but shouldn’t be a big number, 3–5 is reasonable. This will prevent hackers from gaining access to user information via the brute force method.

5. Implement session timeout. Token must be expired in X hr. Again, X is based on business requirements. For a secure app, it shouldn’t be more than 15 minutes to reduce hacker time to access your information.

6. Setting password/pin complexity, which you can learn more from the previous article.

7. Prevent replay attack. For example, you send a payment or order to some website. Even though hackers can’t read your body because of your encryption, they can copy a non-readable body and reuse it again. The result will be a user making a payment again without their permission.

8. Logging in the backend should mask sensitive data to shield it from any internal party.

9. Have 2FA in your Git to prevent source code from leaking. Bear in mind that hackers don’t only attack users, but developers as well.

Optional

1. Detect multiple logins — either disable or send a notification to the user

2. Login notification — send email to the user every time there’s a login

Once implemented the above, let’s make our API more secure.

Secure API Concept

As I’ve mentioned, security is never perfect. There’s no solution in the world that can prevent the hacker 100%, so everyone must try their best to make it as secure as possible. That means making it impossible for anyone to read it. Only the destination will be able to. For that, we come up with the encrypted response from both client and server, which is why I choose “digital signature”.

Digital Signature

For a whole story, please visit the link below.

If you prefer the shorter version, allow me to walk you through.

Credit: https://docs.oracle.com/cd/E19528-01/820-2493/aakfx/index.html

Digital Signature is a concept for encrypting data and checking with hash data to ensure the data integrity. In some countries such as the USA, this is considered as legal as traditional hand-signed documents, which proves that it’s secure and the response can’t be fabricated.

Now that we know digital signature is really safe to use, we will adapt it to our mobile app. Here’s the step-by-step how to with the mobile app and backend.

1. Key Exchange

It’s the process where the server and mobile app exchange keys. Both will create the credential that only both of them knows and use that key to encrypt information while sending over the network. Nonetheless, there’s one security hole which is IF the hacker manages to eavesdrop during the first exchange, the hacker will be able to decrypt the message. Thus the first exchange must be 100% secure. You need to make sure that the exchange key really goes to the end user. So how to do that?

Use trusted network only for the first time

Only allow mobile networks for this. Don’t allow WIFI or local networks to register the first exchange.

Key exchange requires the asymmetric key or public-private key concept. Both platforms (mobile and backend) will generate an asymmetric key. Each will keep the private key to themselves, before sending the public key to each other. The private key in the client side must not be saved in the device in any situation, no exception, and use the generated deviceID to exchange with the server so that the server can map that this deviceID belongs to this private key.

After each platform exchanges public key, we will use that public key to compare with our private key to get another key, or let’s call it body key. We will use this body key to encrypt every message that we send over a network. Hackers won’t be able to decrypt it unless they have the private key that both use. Once the first exchange is done, we can return to use an insecure network to send data.

2. Encrypt Body

Right now, we made sure that the private key that both use is stored in a secure place, except mobile that we only store in memory. We will never ever save it on a device. It’s time to encrypt the body before we send two things to the server:

  1. Content for example JSON
  2. Hashing signature.

3. Create Hashing Signature

Hashing signature is the information proving that this JSON or content that we send is not fabricated, and its origin is from the source only. We use the content you send to calculate with your logic and one-way hash it so that no one can reproduce this hash except you. In the hashing signature, we will add nonce and timestamp.

Nonce is a string of random generated numbers and alphabets to prevent replay attacks. Nonce will be used only once and can’t be reused.

Timestamp is used together with nonce for preventing replay attacks as well. Even if hackers manage to steal the response, they can’t use it because it’s already consumed in the past.

4. Decrypt Body

After receiving the response from the client-side, the server will decrypt with the public key from the key exchange. Decrypted body will be formatted as you agree with frontend, mostly in JSON format.

5. Checking Code Integrity From Signature

Before you use that decrypted response from a client, the server needs to check the code integrity first to make sure that it’s from the client we need by using the same logic as the client used for hashing the content. If the value turns out the same, we will use the content to process it further.

That’s the brief version of digital signature and the implementation concept. Next article will focus more on how to implement it via Flutter.

Want to read more stories like this? Or catch up with the latest trends in the technology world? Be sure to check out our website for more at www.kbtg.tech

--

--

Amorn Apichattanakul
KBTG Life

Google Developer Expert for Flutter & Dart | Senior Flutter/iOS Software Engineer @ KBTG