# Secure Storage in Android: A Comprehensive Guide [PART 5]

When developing Android apps, ensuring secure data storage is essential to protect sensitive information like user credentials, tokens, and other private data from being accessed by unauthorized entities. This article covers essential techniques for secure storage in Android, including **SharedPreferences Encryption**, **SQLite Database Encryption**, and **External Storage Encryption**. Each section includes real-life examples and Kotlin code snippets to help you implement secure storage practices in your Android apps.

---

### **SharedPreferences Encryption: Securing Small Data**

**SharedPreferences** in Android is a commonly used API for storing small amounts of key-value pair data, such as user preferences, session tokens, or flags. However, storing sensitive data in plain text using SharedPreferences can expose it to security risks like rooting or unauthorized app access. To address this, Android provides **EncryptedSharedPreferences**, which encrypts the data stored in SharedPreferences, ensuring that sensitive information is stored securely.

#### **Use Case: Storing Session Tokens Securely**

You may use SharedPreferences to store a session token or other small sensitive data. Using EncryptedSharedPreferences ensures that this data is encrypted and cannot be accessed by unauthorized apps or users.

#### **Kotlin Example: Implementing EncryptedSharedPreferences**

1. Add the necessary dependency to your `build.gradle` file:
    

```kotlin
implementation "androidx.security:security-crypto:1.1.0-alpha03"
```

2. Set up **EncryptedSharedPreferences** in your app:
    

```kotlin
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKeys

fun setupEncryptedSharedPreferences(context: Context) {
    // Generate or retrieve the master key
    val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)

    // Create an instance of EncryptedSharedPreferences
    val sharedPreferences = EncryptedSharedPreferences.create(
        "secure_prefs",
        masterKeyAlias,
        context,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )

    // Store and retrieve encrypted data
    val editor = sharedPreferences.edit()
    editor.putString("auth_token", "1234567890")
    editor.apply()

    val authToken = sharedPreferences.getString("auth_token", null)
    println("Retrieved encrypted token: $authToken")
}
```

In this example, the **EncryptedSharedPreferences** API encrypts both the keys and values of the SharedPreferences, ensuring that sensitive data (like an authentication token) is stored securely.

#### **Real-Life Example: Securing User Preferences**

An e-commerce app might store user settings, such as login session tokens or payment preferences, using SharedPreferences. Storing this data using EncryptedSharedPreferences ensures that attackers cannot easily access or modify the data.

---

### **SQLite Database Encryption: Securing Local Databases**

Android apps often use SQLite databases for local storage of structured data. However, storing sensitive information such as user data or application configurations in plain text databases can expose it to security risks, especially if the device is compromised. To mitigate this, you can use encryption libraries like **SQLCipher** to encrypt the contents of your SQLite database.

#### **Use Case: Encrypting User Data in Local Databases**

If your app stores sensitive user data such as personally identifiable information (PII), you need to encrypt the local SQLite database to protect it from unauthorized access. This is especially important if the device is rooted or the database file is accessed directly.

#### **Kotlin Example: Implementing SQLite Database Encryption with SQLCipher**

1. Add the SQLCipher dependency to your `build.gradle` file:
    

```kotlin
implementation 'net.zetetic:android-database-sqlcipher:4.5.0'
```

2. Create or open an encrypted SQLite database:
    

```kotlin
import net.sqlcipher.database.SQLiteDatabase
import net.sqlcipher.database.SQLiteOpenHelper

class SecureDatabaseHelper(context: Context) : SQLiteOpenHelper(context, "secure_db", null, 1) {

    override fun onCreate(db: SQLiteDatabase) {
        db.execSQL("CREATE TABLE User (id INTEGER PRIMARY KEY, name TEXT, email TEXT)")
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        db.execSQL("DROP TABLE IF EXISTS User")
        onCreate(db)
    }
}

fun getEncryptedDatabase(context: Context, password: String): SQLiteDatabase {
    SQLiteDatabase.loadLibs(context) // Load SQLCipher libraries
    val dbHelper = SecureDatabaseHelper(context)
    return dbHelper.getWritableDatabase(password) // Open encrypted database
}

fun insertEncryptedData(context: Context, password: String) {
    val db = getEncryptedDatabase(context, password)
    val contentValues = ContentValues().apply {
        put("name", "John Doe")
        put("email", "johndoe@example.com")
    }
    db.insert("User", null, contentValues)
    db.close()
}
```

In this example, **SQLCipher** is used to create and manage an encrypted SQLite database. The password provided is used to encrypt and decrypt the database, ensuring that sensitive information remains protected even if the database file is accessed directly.

#### **Real-Life Example: Storing Medical Records**

A health app that stores medical records or user health data locally should use an encrypted SQLite database to ensure that sensitive health information is protected from unauthorized access, even if the device is compromised or rooted.

---

### **External Storage Encryption: Securing Files on External Storage**

Android allows apps to store files on external storage (e.g., SD cards or shared storage). However, files stored in external storage are generally accessible to other apps, and can be read or modified by malicious apps. To secure sensitive files, such as documents or media files, it is crucial to encrypt them before saving to external storage.

#### **Use Case: Encrypting Files Before Saving to External Storage**

If your app needs to store sensitive files like user-generated content, personal documents, or media files, encrypting these files ensures that they cannot be accessed or modified by other apps or attackers with access to the external storage.

#### **Kotlin Example: Encrypting and Saving Files to External Storage**

1. Add the necessary dependency for encryption:
    

```kotlin
implementation 'androidx.security:security-crypto:1.1.0-alpha03'
```

2. Encrypt a file before saving it to external storage:
    

```kotlin
import android.content.Context
import android.os.Environment
import androidx.security.crypto.EncryptedFile
import androidx.security.crypto.MasterKeys
import java.io.File

fun saveEncryptedFile(context: Context, fileName: String, fileContent: String) {
    // Create a master key
    val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)

    // Create a file object for the external storage directory
    val externalFile = File(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), fileName)

    // Create an EncryptedFile object
    val encryptedFile = EncryptedFile.Builder(
        externalFile,
        context,
        masterKeyAlias,
        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
    ).build()

    // Write encrypted content to the file
    encryptedFile.openFileOutput().use { outputStream ->
        outputStream.write(fileContent.toByteArray())
    }

    println("File saved securely in external storage.")
}
```

3. To read the encrypted file, use the corresponding `openFileInput` method:
    

```kotlin
fun readEncryptedFile(context: Context, fileName: String): String {
    val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
    val externalFile = File(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), fileName)

    val encryptedFile = EncryptedFile.Builder(
        externalFile,
        context,
        masterKeyAlias,
        EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB
    ).build()

    return encryptedFile.openFileInput().use { inputStream ->
        inputStream.bufferedReader().readText()
    }
}
```

In this example, **EncryptedFile** is used to encrypt a file before saving it to external storage. This ensures that even if other apps access the file on external storage, they cannot read its contents without the proper decryption key.

#### **Real-Life Example: Encrypting Media Files**

A photo-sharing app that allows users to upload sensitive images might need to store these images locally before uploading. By encrypting the images before saving them to external storage, the app ensures that other apps or malicious actors cannot access or modify the images.

---

### **Conclusion**

Securing data storage in Android is crucial for protecting sensitive user information from unauthorized access. By using **EncryptedSharedPreferences**, you can securely store small key-value pairs such as tokens or flags. For apps that store larger amounts of structured data, libraries like **SQLCipher** can encrypt the contents of SQLite databases. Finally, when storing sensitive files on external storage, **EncryptedFile** ensures that files are encrypted before saving, preventing unauthorized apps from accessing them.

By implementing these secure storage techniques, you can ensure that your Android app remains compliant with security best practices and that sensitive user data is protected from potential threats.

---

That’s it for today. Happy Coding…

%%[buymeacoffee-donate]
