{"record":{"id":"fee0f08375d872ae","repo":"MuntashirAkon/AppManager","slug":"no-saved-password-for-keystore","errorCode":null,"errorMessage":"No saved password for KeyStore.","messagePattern":"No saved password for KeyStore\\.","errorType":"exception","errorClass":"KeyStoreException","httpStatus":null,"severity":"critical","filePath":"app/src/main/java/io/github/muntashirakon/AppManager/crypto/ks/KeyStoreManager.java","lineNumber":477,"sourceCode":"            Utils.clearChars(realPassword);\n        }\n        return keyStore;\n    }\n\n    /**\n     * Get App Manager's KeyStore password. The password is stored in the shared preferences in an\n     * encrypted format (the encryption/decryption is performed via AndroidKeyStore). In case the\n     * user restores from the cache or accidentally deletes all entries from the shared pref, App\n     * Manager will ask for KeyStore password again.\n     *\n     * @return KeyStore password in decrypted format. {@link Utils#clearChars(char[])} must be called when done.\n     */\n    @CheckResult\n    @NonNull\n    public char[] getAmKeyStorePassword() throws KeyStoreException {\n        String encryptedPass = sSharedPreferences.getString(PREF_AM_KEYSTORE_PASS, null);\n        if (encryptedPass == null) {\n            throw new KeyStoreException(\"No saved password for KeyStore.\");\n        }\n        char[] realPassword = getDecryptedPassword(mContext, encryptedPass);\n        if (realPassword == null) {\n            throw new KeyStoreException(\"Could not decrypt encrypted password.\");\n        }\n        return realPassword;\n    }\n\n    /**\n     * @return Password for the given alias. {@link Utils#clearChars(char[])} must be called when done.\n     * @deprecated Kept for migratory purposes only, deprecated since v2.6.3. To be removed in v3.0.0.\n     */\n    @Deprecated\n    @CheckResult\n    @NonNull\n    private char[] getAliasPassword(@NonNull String alias) throws KeyStoreException {\n        char[] password;\n        String prefAlias = getPrefAlias(alias);","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/MuntashirAkon/AppManager/blob/0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5/app/src/main/java/io/github/muntashirakon/AppManager/crypto/ks/KeyStoreManager.java#L459-L495","documentation":"getAmKeyStorePassword reads the encrypted AM keystore password from shared preferences and decrypts it. If no password has ever been saved (PREF_AM_KEYSTORE_PASS absent), it throws KeyStoreException — meaning the AM keystore was never initialized with a password, so keystore operations requiring the password cannot proceed.","triggerScenarios":"Calling getAmKeyStorePassword (via password()/realPassword()) before any key was added to the AM keystore (addKeyPair/addSecretKey never ran), or after app data/keystore was wiped.","commonSituations":"Fresh install querying keys before initialization; cleared app data losing the shared-preferences entry while the keystore file survives; restore that skipped shared preferences.","solutions":["Initialize the keystore by adding a key (addKeyPair/addSecretKey), which creates and persists the password","Detect the missing preference and run first-time keystore setup before any keystore read","If the keystore file itself was lost with the data, start a fresh keystore"],"exampleFix":"// before\nchar[] pass = ksManager.getAmKeyStorePassword(); // throws on fresh install\n// after\nif (PreferenceManager.getDefaultSharedPreferences(ctx).contains(KeyStoreManager.PREF_AM_KEYSTORE_PASS)) {\n    char[] pass = ksManager.getAmKeyStorePassword();\n} else {\n    ksManager.addKeyPair(alias, keyPair, newPassword, false); // initializes password\n}","handlingStrategy":"try-catch","validationCode":"boolean initialized = PreferenceManager.getDefaultSharedPreferences(ctx)\n        .contains(KeyStoreManager.PREF_AM_KEYSTORE_PASS);\nif (!initialized) {\n    runFirstTimeKeystoreSetup();\n}","typeGuard":null,"tryCatchPattern":"try {\n    char[] pass = ksManager.getAmKeyStorePassword();\n} catch (KeyStoreException e) {\n    // no stored password: keystore never initialized or data cleared\n    initializeKeystore();\n}","preventionTips":["Run keystore initialization at app first-launch before any crypto use","Remember shared-preferences data can be wiped independently of the keystore file","Gate all keystore reads behind an isInitialized check"],"tags":["keystore","android","uninitialized-state"],"backgroundTag":"missing-config-value","analyzedSha":"0152f468fc9463ee02dc2ca83f6fe4989a2c4ca5","analyzedAt":"2026-09-12T14:03:37.243Z","contentChangedAt":"2026-09-12T14:03:37.243Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}