MuntashirAkon/AppManager · critical · CryptoException

No SecretKey with alias ${AES_KEY_ALIAS}

Error message

No SecretKey with alias ${AES_KEY_ALIAS}

What it means

AESCrypto's constructor throws this CryptoException in MODE_AES when KeyStoreManager.getSecretKey(AES_KEY_ALIAS) returns null — i.e. the Android keystore has no key under the AES_KEY_ALIAS name. Without that SecretKey, AES-based encrypt/decrypt cannot proceed.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/crypto/AESCrypto.java:68

    }

    @NonNull
    @Override
    public String getModeName() {
        return mParentMode;
    }

    protected AESCrypto(@NonNull byte[] iv, @NonNull @CryptoUtils.Mode String mode, @Nullable byte[] encryptedAesKey)
            throws CryptoException {
        mIv = iv;
        mParentMode = mode;
        switch (mParentMode) {
            case CryptoUtils.MODE_AES:
                try {
                    KeyStoreManager keyStoreManager = KeyStoreManager.getInstance();
                    mSecretKey = keyStoreManager.getSecretKey(AES_KEY_ALIAS);
                    if (mSecretKey == null) {
                        throw new CryptoException("No SecretKey with alias " + AES_KEY_ALIAS);
                    }
                } catch (Exception e) {
                    throw new CryptoException(e);
                }
                break;
            case CryptoUtils.MODE_RSA:
                // Hybrid encryption using RSA
                if (encryptedAesKey == null) {
                    // No encryption key provided, generate one
                    mSecretKey = RSACrypto.generateAesKey();
                } else {
                    // Encryption key provided
                    mSecretKey = RSACrypto.decryptAesKey(encryptedAesKey);
                }
                break;
            case CryptoUtils.MODE_ECC:
                // Hybrid encryption using ECC
                if (encryptedAesKey == null) {

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Generate the key first via KeyStoreManager (ensure a key-generation step runs before AESCrypto is constructed)
  2. Detect the missing key and re-encrypt user data with a freshly generated key, or inform the user data is unrecoverable
  3. Pin/salt AES_KEY_ALIAS handling: never assume key persistence across devices or data clears
  4. Wrap construction in try-catch for CryptoException and route to key-setup flow

Example fix

// before
mSecretKey = keyStoreManager.getSecretKey(AES_KEY_ALIAS);
if (mSecretKey == null) throw new CryptoException("No SecretKey with alias " + AES_KEY_ALIAS);
// after
SecretKey key = keyStoreManager.getSecretKey(AES_KEY_ALIAS);
if (key == null) {
    key = keyStoreManager.generateAesKey(AES_KEY_ALIAS); // create before use
}
mSecretKey = key;
Defensive patterns

Strategy: try-catch

Validate before calling

KeyStoreManager ksm = KeyStoreManager.getInstance();
if (ksm.getSecretKey(AES_KEY_ALIAS) == null) {
    ksm.generateKey(AES_KEY_ALIAS); // provision before use
}

Type guard

boolean hasAesKey() {
    try {
        return KeyStoreManager.getInstance().getSecretKey(AES_KEY_ALIAS) != null;
    } catch (Exception e) {
        return false;
    }
}

Try / catch

try {
    crypto = new AESCrypto(CryptoUtils.MODE_AES);
} catch (CryptoException e) {
    Log.e(TAG, "AES key missing; prompting re-setup", e);
    startKeySetupOrDataResetFlow();
}

Prevention

When it happens

Trigger: Constructing AESCrypto with CryptoUtils.MODE_AES before any key was ever generated under AES_KEY_ALIAS, after app data/keystore wipe (factory reset, clearing app storage), or on a device where keystore key generation silently failed.

Common situations: Restore-from-backup onto a new device where the keystore-backed key was not migrated (keystore keys are non-exportable); users clearing app data; ROM changes invalidating StrongBox/TEE keys.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/3db87994b5d3f205. Report an issue: GitHub.