agentsclimarketplace

Encrypted databases

Skill almasumdev/awesome-mobile-security-agent-skills/.github/skills/storage/encrypted-databases

Agent skills for securing mobile apps: storage, transport, auth, obfuscation, and hardening.

Install
npx -y skills add almasumdev/awesome-mobile-security-agent-skills --skill encrypted-databases

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Encrypting local databases on mobile with SQLCipher, Room + EncryptedFile, or Realm encryption. Use when persisting structured sensitive data on device.

SKILL.md

3.8 KB, as published. Nobody here has run it

Encrypted Databases on Mobile

Instructions

Plain SQLite and plain Realm files are readable by anyone with filesystem access — including forensic tools and, on rooted/jailbroken devices, other apps. Encrypt at rest for anything sensitive.

1. When to Encrypt

Encrypt when the DB contains:

  • Session tokens, refresh tokens, or API credentials.
  • PII (email, phone, address, national IDs).
  • Financial / health records.
  • User-generated content marked private.

Do not encrypt purely public / cached content; it wastes CPU and complicates debugging.

2. Key Management (The Actual Hard Part)

  • Generate a random 256-bit key once per install.
  • Wrap it with a keystore-backed key (Android Keystore / iOS Keychain).
  • Store the wrapped blob in EncryptedSharedPreferences / Keychain.
  • Never derive the DB key from a constant string or from android_id.

3. Android: Room + SQLCipher

// build.gradle.kts
// implementation("net.zetetic:sqlcipher-android:4.6.1")
// implementation("androidx.sqlite:sqlite:2.4.0")

val passphrase: ByteArray = KeyStoreHelper.loadOrCreateDbKey() // 32 bytes
val factory = SupportOpenHelperFactory(passphrase, null, false)

val db = Room.databaseBuilder(ctx, AppDatabase::class.java, "app.db")
    .openHelperFactory(factory)
    .build()

// Zero the passphrase as soon as Room has it.
passphrase.fill(0)

4. Android: Room + EncryptedFile (Alternative)

For small stores where full-text queries are not required, use Jetpack EncryptedFile:

val file = EncryptedFile.Builder(
    ctx, File(ctx.filesDir, "notes.bin"), masterKey,
    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB,
).build()

file.openFileOutput().use { it.write(payload) }

This is simpler than SQLCipher but loses SQL query capabilities.

5. iOS: SQLCipher via GRDB

var config = Configuration()
config.prepareDatabase { db in
    let key = try KeychainHelper.loadOrCreateDbKey() // 32-byte Data
    try db.usePassphrase(key)
}
let dbQueue = try DatabaseQueue(path: path, configuration: config)

For Core Data, wrap the store with NSPersistentStoreFileProtectionKey: FileProtectionType.complete — NOT equivalent to SQLCipher, but acceptable when the device is locked.

6. Realm

val config = RealmConfiguration.Builder(schema = setOf(User::class))
    .name("user.realm")
    .encryptionKey(KeyStoreHelper.loadOrCreateRealmKey()) // 64 bytes
    .build()
val realm = Realm.open(config)

Realm requires a 64-byte key. Losing it means the DB is unrecoverable — plan for re-sync from server on key loss.

7. Migration From Plaintext

If you inherit a plaintext DB:

  1. Open it plaintext.
  2. Attach a new encrypted DB with the new key.
  3. INSERT INTO encrypted.table SELECT * FROM plain.table; for each table.
  4. Close, delete the plaintext file, rename encrypted → canonical path.
  5. Run on a background thread with progress UI; this can take minutes on large DBs.

8. Debug vs Release

  • In debug builds you may want to disable encryption to allow inspection with DB Browser / Stetho. Gate this on BuildConfig.DEBUG / #if DEBUG so it cannot ship.
  • Never commit a debug key that also unlocks production dumps.

Checklist

  • The DB key is random (not derived from a constant or device ID).
  • The DB key is wrapped by Keystore / Keychain and never stored plaintext on disk.
  • SQLCipher / Realm encryption is enabled on any DB containing PII or credentials.
  • A documented migration exists for moving users from plaintext to encrypted DBs.
  • Key-loss UX is handled (re-sync or re-login) rather than silent data corruption.
  • Debug-only relaxations cannot ship to production.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.