Skip to content

Repository files navigation

SecureStorageLabJava

Android application developed in Java to demonstrate secure local data persistence on Android. The lab covers SharedPreferences, EncryptedSharedPreferences, internal files, cache storage, app-specific external storage, and secure data cleanup.

PlatformLanguageMinSDKStorageSecurity

Learning Objective

The objective of this lab is to understand the different forms of local persistence available on Android while applying fundamental security practices.

The application demonstrates:

  • writing and reading non-sensitive data with SharedPreferences;
  • the difference between apply() and commit();
  • securely storing a token with EncryptedSharedPreferences;
  • using a MasterKey based on Android Keystore;
  • writing and reading UTF-8 internal files;
  • saving and loading a local JSON file;
  • using the cache directory with cacheDir;
  • exporting a file to app-specific external storage;
  • completely clearing local application data;
  • verifying that secrets are never exposed in plaintext through Logcat.

Demo Video

demo8.mp4

Application Overview

The application contains a single screen with:

  • a username field;
  • a language list containing fr, en, and ar;
  • a dark-theme switch;
  • a masked token field;
  • buttons for saving and loading data;
  • buttons for managing JSON files;
  • buttons for exporting and reading an app-specific external file;
  • a button for completely clearing local data;
  • an area for displaying operation results.

Features

FeatureDescription
SharedPreferencesSaves the username, language, and theme
apply()Saves preferences asynchronously
commit()Saves preferences synchronously and returns a boolean result
EncryptedSharedPreferencesStores the token in encrypted form
MasterKeyGenerates an encryption key based on Android Keystore
Internal filesSaves note.txt using UTF-8 encoding
Local JSONSaves a list of students in students.json
CacheWrites a temporary last_ui.txt file to cacheDir
App-specific external storageExports an export.txt file to the application's external directory
Data cleanupDeletes preferences, internal files, cache files, and the external export
SecurityNever displays the token in plaintext in the interface or Logcat

Project Architecture

app/src/main/java/com/example/securestoragejava/
│
├── ui/
│ └── MainActivity.java
│
├── prefs/
│ ├── AppPrefs.java
│ └── SecurePrefs.java
│
├── files/
│ ├── InternalTextStore.java
│ └── StudentsJsonStore.java
│
├── cache/
│ └── CacheStore.java
│
├── external/
│ └── ExternalAppFilesStore.java
│
└── model/
└── Student.java

File Descriptions

FileRole
MainActivity.javaManages the main interface and user actions
AppPrefs.javaStores non-sensitive preferences
SecurePrefs.javaStores the token using EncryptedSharedPreferences
InternalTextStore.javaReads and writes UTF-8 internal files
StudentsJsonStore.javaSaves and loads a list of students in JSON format
CacheStore.javaManages a temporary file in cacheDir
ExternalAppFilesStore.javaExports and reads an app-specific external file
Student.javaModel representing a student

Dependency

The lab uses AndroidX Security Crypto for encrypted storage:

implementation("androidx.security:security-crypto:1.1.0-alpha06")

This dependency provides:

  • MasterKey;
  • EncryptedSharedPreferences.

Android Concepts

ConceptUsage
SharedPreferencesSimple key-value storage
EncryptedSharedPreferencesEncrypted key-value storage
MasterKeyKeystore-backed encryption key
MODE_PRIVATEStorage private to the application
openFileOutput()Writes data to internal storage
openFileInput()Reads data from internal storage
cacheDirTemporary cache directory
getExternalFilesDir(null)App-specific external storage
org.jsonCreates and reads JSON data
LogcatVerifies logs for the absence of secret leakage

Stored Data

DataLocationSensitive?Protection
UsernameSharedPreferencesNoMODE_PRIVATE
LanguageSharedPreferencesNoMODE_PRIVATE
ThemeSharedPreferencesNoMODE_PRIVATE
TokenEncryptedSharedPreferencesYesEncryption
note.txtInternal storageNon-sensitiveMODE_PRIVATE
students.jsonInternal storageNon-sensitiveMODE_PRIVATE
last_ui.txtCacheTemporaryPrivate cache
export.txtApp-specific external storageNon-sensitiveApplication directory

Applied Security Measures

The following security rules were applied:

  • the token is never displayed in plaintext in the interface;
  • the token is never written in plaintext to Logcat;
  • only the token length is displayed through tokenLength;
  • standard preferences use MODE_PRIVATE;
  • secrets are stored using EncryptedSharedPreferences;
  • internal files remain private to the application;
  • the cache is used only for temporary data;
  • external exports are limited to the app-specific directory;
  • a button allows complete data cleanup;
  • exceptions are handled without exposing secrets.

Tests Performed

TestExpected Result
Application startupThe main screen is displayed
Save preferencesThe username, language, and theme are saved
Load preferencesValues are restored from SharedPreferences
Save tokenThe token is stored in encrypted form
Load tokenOnly tokenLength is displayed
Save JSON filestudents.json and note.txt are created
Load JSON fileThe note and students are displayed
External exportexport.txt is created in app-specific external storage
Read external exportThe content of export.txt is displayed
Clear allPreferences, files, cache, and external export are deleted
LogcatThe plaintext token is never leaked

Verification with Device File Explorer

After running the application, the files can be inspected using Android Studio.

Internal files path:

/data/data/com.example.securestoragejava/files/

Expected files:

note.txt
students.json

Cache path:

/data/data/com.example.securestoragejava/cache/

Expected file:

last_ui.txt

Preferences path:

/data/data/com.example.securestoragejava/shared_prefs/

Expected files:

app_prefs.xml
secure_prefs.xml

App-specific external export path:

/storage/emulated/0/Android/data/com.example.securestoragejava/files/export.txt

Screenshots

Create the following directory:

docs/screenshots/

Add the following screenshots:

docs/screenshots/01_home_screen.png
docs/screenshots/02_save_prefs.png
docs/screenshots/03_load_prefs.png
docs/screenshots/04_logcat_no_token.png
docs/screenshots/05_save_json.png
docs/screenshots/06_load_json.png
docs/screenshots/07_device_file_explorer_files.png
docs/screenshots/08_shared_prefs_secure.png
docs/screenshots/09_external_export.png
docs/screenshots/10_clear_all.png

Example README integration:

![Main screen](docs/screenshots/01_home_screen.png)![Save preferences](docs/screenshots/02_save_prefs.png)![Load preferences](docs/screenshots/03_load_prefs.png)![Logcat without token](docs/screenshots/04_logcat_no_token.png)![Save JSON](docs/screenshots/05_save_json.png)![Load JSON](docs/screenshots/06_load_json.png)![Device File Explorer](docs/screenshots/07_device_file_explorer_files.png)![Secure SharedPreferences](docs/screenshots/08_shared_prefs_secure.png)![External export](docs/screenshots/09_external_export.png)![Data cleanup](docs/screenshots/10_clear_all.png)

Git Commands Used

git init
git remote add origin https://github.com/bgoussama/SecureStorageLabJava.git
git add .
git commit -m "Add SecureStorageLabJava Android project"
git push -u origin feature/M6-frontend

If the remote already exists:

git remote set-url origin https://github.com/bgoussama/SecureStorageLabJava.git

Running the Project

  1. Clone the repository:
git clone https://github.com/bgoussama/SecureStorageLabJava.git
  1. Open the project in Android Studio.

  2. Synchronize Gradle.

  3. Run the application on an emulator or Android device.

  4. Test the following features:

    • saving preferences;
    • loading preferences;
    • encrypted token storage;
    • saving JSON data;
    • exporting to external storage;
    • completely clearing local data.

Results

The application works without an Internet connection and demonstrates several Android local persistence mechanisms.

It shows how to store standard preferences, protect a token through encryption, write internal files, manage temporary cache data, export a file to app-specific external storage, and securely clear stored data.

Conclusion

This lab validates the fundamentals of secure local persistence on Android using Java.

It highlights the difference between non-sensitive and sensitive data and demonstrates why tokens must never be stored in plaintext or displayed in Logcat.

The solution follows key security practices: MODE_PRIVATE, EncryptedSharedPreferences, no sensitive logging, private internal files, temporary cache usage, and complete data cleanup.

About

Android Java lab demonstrating secure local storage with Android Keystore, EncryptedSharedPreferences, internal files, cache, and secure data cleanup.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages