A secure, blazing-fast alternative to EncryptedSharedPreferences
, designed for Android projects which demand both speed and security.
As of Jetpack Security 1.1.0-alpha07 (April 9, 2025), EncryptedSharedPreferences
has been deprecated with no official replacement. Without continued support from Google, it may fall behind in cryptography standards, leaving sensitive data exposed.
SafeBox can help you migrate easily using the same SharedPreferences
API.
Feature | SafeBox v1.2.0 | EncryptedSharedPreferences |
---|---|---|
Initialization Time | 0.21ms (184.3Γ faster) | 38.7ms |
Storage Format | Memory-mapped binary file | XML-based per-entry |
Encryption Method | ChaCha20-Poly1305 (keys & values) | AES-SIV for keys, AES-GCM for values |
Key Security | Android Keystore-backed AES-GCM | Android Keystore MasterKey (deprecated) |
Customization | Pluggable cipher providers | Tightly coupled |
SafeBox uses deterministic encryption for reference keys (for fast lookup) and non-deterministic encryption for values (for strong security). Both powered by a single ChaCha20 key protected via AES-GCM and stored securely.
π SafeBox Key Derivation & Encryption Flow
[Android Keystore-backed AES-GCM Key]
β
[ChaCha20-Poly1305 Key]
β β
Reference Keys Entry Values
(deterministic IV) (randomized IV)
Compared to EncryptedSharedPreferences:
[Android Keystore MasterKey (deprecated)]
β β
[AES-SIV Key] [AES-GCM Key]
β β
Reference Keys Entry Values
dependencies {
implementation("io.github.harrytmthy:safebox:1.3.0-alpha01")
// Optional: standalone crypto helper
implementation("io.github.harrytmthy:safebox-crypto:1.3.0-alpha01")
}
Create the instance:
val prefs: SharedPreferences = SafeBox.create(context, PREF_FILE_NAME)
Then use it like any SharedPreferences
:
prefs.edit()
.putInt("userId", 123)
.putString("name", "Luna Moonlight")
.apply()
val userId = prefs.getInt("userId", -1)
val email = prefs.getString("email", null)
Once created, you can retrieve the same instance without a Context
:
SafeBox.get(PREF_FILE_NAME) // or SafeBox.create(context, PREF_FILE_NAME)
.edit()
.clear()
.commit()
Prefer
SafeBox.getOrNull(fileName)
if you need a safe retrieval without throwing.
SafeBox returns the same instance per filename:
val a1 = SafeBox.create(context, "fileA")
val a2 = SafeBox.create(context, "fileA")
val a3 = SafeBox.get("fileA")
assertTrue(a1 === a2) // same reference
assertTrue(a1 === a3) // same reference
val b = SafeBox.create(context, "fileB")
assertTrue(a1 !== b) // different filenames = different instances
Repeating
SafeBox.create(context, fileName)
returns the existing instance for thatfileName
. When an instance already exists, all parameters are ignored except a non-nullstateListener
, which replaces the current listener.
Need lifecycle hooks for diagnostics or analytics? β‘οΈ Read the Observability Guide
SafeBox is a drop-in replacement for EncryptedSharedPreferences
.
β‘οΈ Read the Migration Guide
SafeBox includes a simple text encryption helper (SafeBoxCrypto
) you can use for things like
encrypting values before writing to Room or sending over the network:
// 1. Create a secret and store it in your own vault
val secret: String = SafeBoxCrypto.createSecret()
// 2. Use it to encrypt
val userEntity = UserEntity(
id = SafeBoxCrypto.encrypt(userId, secret),
// ...
)
// 3. Retrieve it later
val userId: String = SafeBoxCrypto.decrypt(userEntity.id, secret)
If you only need the helper, use the standalone :safebox-crypto
module.
Average times measured over 100 samples on an emulator:
π v1.2.0 Benchmark
Operation | SafeBox v1.2.0 | EncryptedSharedPreferences |
---|---|---|
Initialization | 0.21ms (184.3Γ faster) | 38.7ms |
Get 1 entry | 0.01ms (50.0Γ faster) | 0.50ms |
Get 3 entries | 0.04ms (31.8Γ faster) | 1.27ms |
Get 5 entries | 0.07ms (32.1Γ faster) | 2.25ms |
Get 10 entries | 0.15ms (27.1Γ faster) | 4.07ms |
Put 1 entry, then commit | 0.22ms (5.95Γ faster) | 1.31ms |
Put 3 entries, then commit | 0.52ms (4.15Γ faster) | 2.16ms |
Put 5 entries, then commit | 0.98ms (3.39Γ faster) | 3.32ms |
Put 10 entries, then commit | 1.64ms (3.83Γ faster) | 6.28ms |
Even on multiple single commits, SafeBox remains faster:
Operation | SafeBox v1.2.0 | EncryptedSharedPreferences |
---|---|---|
Commit 3 single entries | 0.53ms (9.25Γ faster) | 4.90ms |
Commit 5 single entries | 0.95ms (7.27Γ faster) | 6.91ms |
Commit 10 single entries | 1.96ms (5.75Γ faster) | 11.27ms |
Commit 100 single entries | 17.41ms (4.10Γ faster) | 71.34ms |
π v1.1.0 Benchmark
Operation | SafeBox v1.1.0 | EncryptedSharedPreferences |
---|---|---|
Initialization | 0.38ms | 38.7ms (10,079% slower) |
Get 1 entry | 0.33ms | 0.50ms (52% slower) |
Get 3 entries | 0.94ms | 1.27ms (35% slower) |
Get 5 entries | 1.56ms | 2.25ms (44% slower) |
Get 10 entries | 3.06ms | 4.07ms (33% slower) |
Put 1 entry, then commit | 0.49ms | 1.31ms (167% slower) |
Put 3 entries, then commit | 1.34ms | 2.16ms (61% slower) |
Put 5 entries, then commit | 2.36ms | 3.32ms (41% slower) |
Put 10 entries, then commit | 4.20ms | 6.28ms (50% slower) |
Even on multiple single commits, SafeBox remains faster:
Operation | SafeBox v1.1.0 | EncryptedSharedPreferences |
---|---|---|
Commit 3 single entries | 1.50ms | 4.90ms (227% slower) |
Commit 5 single entries | 2.39ms | 6.91ms (189% slower) |
Commit 10 single entries | 5.07ms | 11.27ms (122% slower) |
Commit 100 single entries | 38.12ms | 71.34ms (87% slower) |
π v1.0.0 Benchmark
Operation | SafeBox v1.0.0 | EncryptedSharedPreferences |
---|---|---|
Get 1 entry | 0.39ms | 0.50ms (28% slower) |
Get 3 entries | 0.94ms | 1.27ms (35% slower) |
Get 5 entries | 1.37ms | 2.25ms (64% slower) |
Get 10 entries | 3.29ms | 4.07ms (24% slower) |
Put 1 entry, then commit | 0.55ms | 1.31ms (138% slower) |
Put 3 entries, then commit | 1.25ms | 2.16ms (73% slower) |
Put 5 entries, then commit | 2.33ms | 3.32ms (42% slower) |
Put 10 entries, then commit | 4.73ms | 6.28ms (33% slower) |
Even on multiple single commits, SafeBox remains faster:
Operation | SafeBox v1.0.0 | EncryptedSharedPreferences |
---|---|---|
Commit 3 single entries | 1.94ms | 4.90ms (152% slower) |
Commit 5 single entries | 2.84ms | 6.91ms (143% slower) |
Commit 10 single entries | 5.47ms | 11.27ms (106% slower) |
Commit 100 single entries | 33.19ms | 71.34ms (115% slower) |
See CONTRIBUTING.md for setup, formatting, testing, and PR guidelines.
If SafeBox helped secure your app or saved your time, consider sponsoring to support future improvements and maintenance!
MIT License
Copyright (c) 2025 Harry Timothy Tumalewa