Skip to content

simons-hub/android-encrypted-storage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

android-encrypted-storage

License: MIT Kotlin Android

AES-256/GCM encryption for Android images and databases, backed by Android Keystore.

Features

  • Image/file encryption — AES-256/GCM with streaming support for large files
  • Bitmap encryption — encrypt/decrypt Android Bitmaps directly to/from files
  • Key management — hardware-backed keys via Android Keystore with rotation and recovery
  • Database encryption — SQLCipher integration with Room, using Keystore-protected keys
  • Password hashing — PBKDF2-HMAC-SHA256 for password verification
  • In-place encryption — safe to encrypt a file to itself (uses temp file internally)

Security Model

Layer Algorithm Key Storage
Image encryption AES-256/GCM, 128-bit tag, 12-byte IV Android Keystore (hardware-backed)
Database encryption SQLCipher (AES-256-CBC) Random key encrypted with Keystore master key, stored in SharedPreferences
Password hashing PBKDF2-HMAC-SHA256, 10K iterations N/A (verification only)

Keys never leave the Android Keystore. The IV is prepended to each ciphertext, making encrypted files self-contained.

Usage

Encrypt/decrypt files

val key = KeyManager.getOrCreateImageKey()
val encryption = ImageEncryption(key)

// Encrypt a file
encryption.encryptFile(inputFile, outputFile)

// Decrypt it back
encryption.decryptFile(outputFile, decryptedFile)

// Encrypt a Bitmap directly
encryption.encryptBitmapToFile(bitmap, encryptedFile, quality = 90)

// Decrypt back to Bitmap
val bitmap = encryption.decryptFileToBitmap(encryptedFile)

Encrypted Room database

@Database(entities = [MyEntity::class], version = 1)
abstract class MyDatabase : RoomDatabase() {
    abstract fun myDao(): MyDao
}

val db = EncryptedDatabaseBuilder.build(
    context = applicationContext,
    klass = MyDatabase::class.java,
    name = "my_encrypted_db"
)

Password hashing

val salt = PasswordUtils.generateSalt()
val hash = PasswordUtils.hashPassword("user_password", salt)
// Store salt + hash; verify by re-hashing and comparing

Key Recovery

The database key includes retry logic for transient Keystore errors. For user-initiated recovery (e.g., after a factory reset that invalidates Keystore keys):

val db = EncryptedDatabaseBuilder.build(
    context = context,
    klass = MyDatabase::class.java,
    name = "my_db",
    allowKeyRegeneration = true  // WARNING: old data becomes unreadable
)

Dependencies

Library Purpose
net.zetetic:sqlcipher-android SQLCipher database encryption
androidx.room:room-runtime Room database abstraction
androidx.sqlite:sqlite-framework SQLite support

Installation

Copy the com.simonshub.encryptedstorage package into your project, or include as a module dependency.

License

MIT License. See LICENSE for details.

About

AES-256/GCM encryption for Android images and databases, backed by Android Keystore + SQLCipher

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages