Table of content
The wrong security architecture can lead to compromised user data and totally break backend data protection. Data safety is especially important in fintech projects, where security must always be on a high level because a tiny mistake is a fat wad of real money. So how is data encrypted while using mobile applications and how to ensure a reasonable level of data protection?
In my experience as Android Engineer, I have developed the algorithm that helped us to strengthen the protection of the user data on a fintech app.
In this article, I'm going to describe the data protection algorithm by giving a step-by-step implementation guide. The description will be abstract without any code, and the specification is very flexible and can be modified and improved to fit others' needs. I will also suggest the tools that can help implement any complex algorithm. Let’s start!
The implementation of the algorithm has highly relied on the project requirements we received. The main feature was offline support, allowing users to interact with the application without the Internet. The second one was the performance. For example, the delay for transaction creation must be unnoticeable for users (less than 1 second).
Before diving into the developed algorithm details, let's review the usual implementation and its pitfalls.
Common Data Encryption Algorithm
Usually, after the authentication, the user's authentication and refreshed tokens are stored as encrypted files on the device. The master key for the encryption is located in the Android Keystore. The security of the Android Keystore is managed by the operating system and can be backed by secure hardware.
Uptech tip: All developers should develop their security algorithms assuming that Android Keystore is the safest place in the local environment.
The above-described algorithm is the most common for token protection, as it does not include any additional steps. When tokens are put in the Android Keystore, the developer can use them during the authenticated requests.
Vulnerabilities of Common Data Encryption Algorithm
The problem with the described security algorithm is that the developer doesn't care about the user’s data, such as: databases, preferences, etc. Instead, the data is stored as plain text and can be extracted from the device easily.
The common solution for such a case is refusing to store the local data at all. No data – no vulnerabilities. But when the main requirement is the ability to view and modify the data offline, then the data is usually left as it is, without any encryption. In addition, even when the user logs out, the data is still stored on the device because otherwise all the offline changes will be lost.
Let's see the consequences of such a simple solution.
Authentication token is expired
Let's imagine that the phone was stolen and the authentication token expired. In this situation, the hackers won't receive access to our server, but they can acquire all the user data because it is stored as plain text on the device. Moreover, in the most unlikely case, the hacker can modify the local data and give the device back to the user. And then, when the user logs in, all the hacked local modifications will be transferred to the server.
Authentication token is not expired
If the phone was stolen and the authentication token didn't expire, the hacker can still access all the user data. Whether the token will extract or not is fully based on the Android Keystore reliability.
So, in both situations, the hackers can access the user data, and based on the Android Keystore reliability, they can gain full access to the server data.
We have developed 7 fintech products 📲
Check out financial software development services we offer
How to Ensure Mobile Data Encryption: Advanced Algorithms
The main weak spot of the described security system is that the user data is stored unencrypted. Of course, we can prompt users to enter the pin code or provide the fingerprint each time they open the application. Then, we could encrypt and decrypt the local data. That's a well-worked and simple solution, but it highly relies on the device's security hardware.
Data encryption using the session token
To reduce the dependence on the security hardware, we introduce an additional token from the backend and use it inside our algorithm. Let's call this token – the session token. It will be created and stored on the backend each time when the client logs in.
Now, when the user logs out without the Internet, all the locally modified data is encrypted using this token, and the token must be erased. In this case, the hacker won't be able to decrypt and encrypt this data (Figure 1).
When users come back online during the authorization, they will receive the token from the previous session and will be able to decrypt all the local data they modified offline. The algorithm schema is below:
Data encryption using an asymmetric algorithm
First, there is no need to store the token, which can be used for both: encryption and decryption. We can use a key for an asymmetric algorithm and store locally only the one that can be used for the encryption. And then generate the one used for the decryption when we receive the previous session token.
Data encryption using a symmetric algorithm in tandem with asymmetric keys
Since we shouldn't use the asymmetric algorithm for long data stream encryption/decryption, we should apply the symmetric encryption algorithm. By the way, if you ever wonder what type of encryption algorithm uses the same key to encrypt data and decrypt data? This is symmetric encryption.
Let's get familiar with some namings to make it all clear:
- ASYM_ENC / ASYM_DEC – encryption/decryption key of the asymmetric algorithm;
- SYM_KEY – encryption/decryption key of the symmetric algorithm.
We should generate SYM_KEY and use it for user data encryption (Figure 3). After we encrypt the user data, we should encrypt the SYM_KEY using the ASYM_ENC. And store it locally. After the user logs in, we will generate ASYM_DEC and decrypt the SYM_KEY.
All the stored keys should be encrypted using the Android Keystore master key for more robust security.
The last thing to view in detail is the lifecycle of the session token. The session token is created together with the authentication token on the login request and stored in the database. The user can access the previous session token only when the new session token is created (Figure 4). The users will be able to decrypt the data only after the new successful login. A separate request must erase the previous session token, and that is why:
If the login request data isn't received by the client, for example, due to connection interruption, then the previous session token will be lost. So, the client should manually request the previous session token after the successful login and manually request the erase of the previous session token after successful data decryption.
Why Your System Will Be Hacked Anyway
As any system, the described algorithm is still prone to be hacked. Offline data modification support requires us to encrypt the data only when the user logs out. What does it mean? The data is stored as clear text as long as the user's session is not expired, and therefore it can be accessed by hackers when they receive physical access to the device.
The better approach will be to additionally encrypt the data every time the user closes the app. The key for the encryption should be taken from the Android Keystore. But when we work with a large amount of data, for example, thousands of store goods, the cryptography operations could take a noticeable amount of time.
So, the decision is up to the product owner, what is more important: the data security or the user experience?
Tools I Recommend For Implementation
The cryptography is well studied; all is already written and can be used without modifications. For Android Keystore master key management, there is a library called Jetpack Security. There is little space for mistakes, and you can simply follow its recommendation. You can find the documentation for this library on the official Android Developers site. There is also a perfect library for advanced cryptography operations called Tink developed by Google. It also supports the Android Keystore. We used this library for implementing the described algorithm with session tokens.
If an algorithm requires more complex operations and Tink is not enough, then I recommend the Bouncy Castle library. It has additional algorithms support and java security package wrappers for easier usage.
In this article, I described the algorithms we use for our project. It is not a straightforward solution for all cases, and the algorithm is always based on the project and data security requirements. Personalization matters! We at Uptech approach every new project with an open mind, we dive into clients' businesses, ask questions, conduct tech discovery, and create solutions that perfectly match your business goals and users' needs. If you have a product idea but lack development expertise, contact us. We'll be happy to work together!
The most useful advice I could give is – if something is already implemented, use it instead of writing something yourself. It's related to the security field, especially because you can make a tiny mistake that can lead to a giant vulnerability.
The algorithm was developed together with my coworker Eduard Shvets. Big thanks for his help and support.