Skip to content

securePrefs() recreates EncryptedSharedPreferences on every call #5

Description

@rogue-socket

Summary

ScrollerApp.securePrefs() (line 51) is a plain function that calls EncryptedSharedPreferences.create() + MasterKey.Builder().build() on every invocation. This involves Android Keystore access and Tink crypto initialization, costing 25-100ms per call.

Impact

Performance: Normal app lifecycle involves 6 calls (3 reads in onCreate + 3 writes during use) = 150-600ms of crypto overhead. The 3 onCreate calls happen on the main thread, adding 75-300ms to app startup.

Thread safety: Concurrent calls from different threads create multiple EncryptedSharedPreferences instances on the same backing file, which can cause BadPaddingException, IllegalBlockSizeException, or divide-by-zero in Tink internals.

Call sites

Line Method Thread
46 onCreate() — read KEY_API Main
47 onCreate() — read KEY_MODEL Main
48 onCreate() — read KEY_GOAL Main
25 setLlmApiKey() Caller
32 setLlmModel() Caller
39 setLastGoal() Caller

Fix

Replace the function with a lazily-initialized property:

private val securePrefs: SharedPreferences by lazy {
    EncryptedSharedPreferences.create(
        this, PREFS_NAME,
        MasterKey.Builder(this).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build(),
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    )
}

Kotlin by lazy is SYNCHRONIZED by default, fixing both performance (single creation) and thread safety.

Files

  • app/src/main/java/com/scroller/agent/ScrollerApp.kt (lines 51-57)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions