Writing secure android applications – storing data

In this article I’m going to talk through options for storing files securely on device, on android. We will need to consider a number of factors before storing any files, including;

  • Does this file need to be shared with other applications?
  • Does this file need to be stored on the sdcard?
  • Does your app have a Pin / password / fingerprint in order to enter the app?
  • Is the data synchronised to the server?
  • Is two factor authentication a practical solution for your application?

Some other considerations are the type of data you’re trying to store, some obvious examples are

  • Room or some other sql backed database
  • Shared preferences
  • Files on disk

Location

Private

When your data is stored, on disk you need to consider the location. Broadly speaking, we have two main places to store data. On the shared, external storage or in private internal storage. The default response should usually be to store it on your internal, private storage. To do this, use the directory or subdirectory:

getFilesDir()

Using this as the base directory for your files means that without some kind of comprise or you introducing another mechanism for sharing the file, the file cannot be read.

For our other two main types of data storage, a database using sqlite, sqldelight or room the defaults will store files in our private directory.

val db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "database-name"
).build()

In this example the default directory is used — e.g. a private one. Again, this means in effect that there is no way for an attacker to access the database without some other vulnerability.

Finally, the most common way of storing key value pairs is shared preferences, which are again, by default stored in your private file storage.

val sharedPref = activity?.getSharedPreferences(
getString(R.string.preference_file_key), Context.MODE_PRIVATE)

Public

Moving on now to the storing data in a public location, there are three things to note about storing things in a public place;

  1. Placing your files in a public place does not allow you to control — through permissions or otherwise — who is able to access the files.
  2. There are ways of sharing files with other apps which are less permissive
  3. Little or no protection is provided for externally stored files with removable media when a phone is lost or stolen.

Depending on the type of data you want to store externally, you are advised to use either https://developer.android.com/training/data-storage/shared/media or https://developer.android.com/training/data-storage/shared/documents-files depending on if you’re storing media (videos, pictures, audio) or documents.

There is also the option of replacing previous usages of

getFilesDir()// WithgetExternalFilesDir()

to make your files accessible from the SDCard.

Rule of thumb: If you don’t need files to be accessible to other applications like file managers — store things in a private directory.

Sharing data with other applications

Depending on the type of data you want to share with other applications, it is recommended to use:

For sharing small amounts of data, or else

for sharing files.

Finally, use

for sharing data stored in a database or for sharing other structure content.

Security considerations when sharing data

When sharing data with other applications, you need to consider the following things:

  1. Is it appropriate for the application to request a permission before being able access your apps data
  2. Is a user able to modify any data stored in my database? Are they able to modify files? Are they able to replace or delete files?
  3. Is it clear to the user which application is getting access to their data, and is it clear which bits of data they can access?
  4. Can your mechanism for sharing one file be abused to give access to another file?

Rule of thumb: provide the least access needed for other applications to do their job

Encryption

In our next article we’ll conver in depth how to encrypt shared preferences, files and databases but for now let’s discuss the benefits of encrypting files.

In short, an encrypted file cannot be read without the decryption key, and a file cannot be modified without the encryption key (or else it will be corrupted / destroyed). One thing to note is that a file that is encrypted with no other protection can be deleted or re-encrypted for example by ransom ware. This is an important distinction between encrypting your file on the sdcard, or storing it in a private location.

Another key differentiation between private storage and encryption in a public place is the ability to decrypt it. As we’ll discuss in a moment, there are two main ways of generating an encryption key securely — either using secure random and storing it in the android keystore or a password based key derivation algorithm. The weakness of the former is that the implementation of the keystore may vary from device to device, on newer devices it’s likely to be backed by hardware encryption whereas the latter has the same vulnerabilities as is usual with user generated passwords e.g. they can be lost, forgotten, too short or written down. That said, encrypting your files that need to be protected is an incredibly effective security measure, and there are two things to consider when doing so:

  • Which algorithm will be used for encryption
  • How will you be generating the key.

The algorithm

The algorithm suggested by Google is `MasterKeys.AES256_GCM_SPEC` which is an industry standard for encryption. There are other perfectly good algorithms for symmetric encryption, but there isn’t often a need to use any but aes

Generating keys

There are two ways I’m going to describe to generate keys, these are the best recommendations for generating encryption keys on Android; there is however a situation where you need to encrypt files that are used by the server — we will cover this another time.

  1. When a file only ever needs to be encrypted and decrypted on the same phone, and the user does not have to enter a pin or password
  2. When a user does need to enter a password and the file can either be decrypted on or off the device

On device, no password

The first method is provided for us in the android security library

```

keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC
val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)
```

In this case, encryption is done using the android keystore, on newer phones it is done using a specific piece of hardware used for security and is therefore not vulnerable to more common android vulnerabilities. Finally, the way it works is by handling the encryption and decryption for you which means there’s no storage of the master key anywhere that it might be leaked (easily).

On device, password

The specific implementation of a password based encryption we’ll cover later but for now we’ll cover the general idea of using a password for encryption.

Don’t just use the password as a key

There is a debate about the algorithm best used on Android for password based key derivation, but we would recommend PBKDF2 which is an algorithm taking a user password and providing a key. There are some security issues with this which are addressed by other algorithms such as bcrypt, however without native support for bcrypt we would suggest PBKDF2.

The flow for encryption is as follows:

  • Capture user passwords
  • Ensure it meets criteria of length, uppercase and lowercase, numbers and special characters
  • Pass the password into the PBKDF2 algorithm
  • Use the output to encrypt your data

Summary

For maximising security, you should

  • Store data in a private location within your application sandbox
  • Encrypt the file with either the keystore or a password (or both)
  • Share the file using the appropriate API for the task, ensure your user is aware of how the file is being shared and

--

--

--

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Reviewing big pull requests. What, why, how.

AWS Batch: Automating Your Workflows

Start a Blog With Eleventy

A stacked pile of assorted books with a peach coloured coffee cup on top.

How to create High Availability Architecture with AWS CLI

Lessons from moving DomeCode to DigitalOcean

Get Chromium Real-Time Prices With This API

XSlope: A Xamarin Reference Architecture

Walk-in for 3 Project Scientist, Project Senior Research Fellow, Project Computer Programmer…

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Daniel Llewellyn

Daniel Llewellyn

More from Medium

How to Implement Android QR Scanner with NDK Camera2 API

CI-CD: Install Nexus to Local Machine

Android-Pentesting- Android Appsec (Kotlin) HTTP & HTTPS Traffic

Using custom keystore in android gradle