MuntashirAkon/AppManager · error · CryptoException

No KeyPair with alias RSA_KEY_ALIAS

Error message

No KeyPair with alias RSA_KEY_ALIAS

What it means

RSACrypto.encryptAesKey needs the RSA KeyPair under RSA_KEY_ALIAS to wrap the session AES key. When KeyStoreManager returns null (no such entry) or throws, CryptoException is thrown, aborting encryption.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/crypto/RSACrypto.java:84

            Cipher cipher = Cipher.getInstance(RSA_CIPHER_TYPE);
            cipher.init(Cipher.DECRYPT_MODE, keyPair.getPrivateKey());
            return new SecretKeySpec(cipher.doFinal(encryptedAesKey), "AES");
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException
                | IllegalBlockSizeException e) {
            throw new CryptoException(e);
        }
    }

    @NonNull
    static byte[] encryptAesKey(@NonNull SecretKey key) throws CryptoException {
        // We only have 32/64 bytes AES key with either 256 or 512 bytes minus 42 bytes of data,
        // so it should work without issues
        KeyPair keyPair;
        try {
            KeyStoreManager keyStoreManager = KeyStoreManager.getInstance();
            keyPair = keyStoreManager.getKeyPair(RSA_KEY_ALIAS);
            if (keyPair == null) {
                throw new CryptoException("No KeyPair with alias " + RSA_KEY_ALIAS);
            }
        } catch (Exception e) {
            throw new CryptoException(e);
        }
        try {
            Cipher cipher = Cipher.getInstance(RSA_CIPHER_TYPE);
            cipher.init(Cipher.ENCRYPT_MODE, keyPair.getPublicKey());
            return cipher.doFinal(key.getEncoded());
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | BadPaddingException
                | IllegalBlockSizeException e) {
            throw new CryptoException(e);
        }
    }
}

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Generate the RSA key pair for RSA_KEY_ALIAS via KeyStoreManager before encrypting
  2. Verify AndroidKeyStore availability and that no ProviderException is wrapped in the CryptoException
  3. Recreate the crypto instance after key generation so it picks up the new KeyPair

Example fix

// before
byte[] enc = RSACrypto.encryptAesKey(aesKey); // no keypair yet
// after
KeyStoreManager ksm = KeyStoreManager.getInstance();
if (ksm.getKeyPair(RSA_KEY_ALIAS) == null) ksm.generateKeyPair(RSA_KEY_ALIAS);
byte[] enc = RSACrypto.encryptAesKey(aesKey);
Defensive patterns

Strategy: validation

Validate before calling

KeyPair kp = KeyStoreManager.getInstance().getKeyPair(RSA_KEY_ALIAS);
if (kp == null) {
    KeyStoreManager.getInstance().generateKeyPair(RSA_KEY_ALIAS);
}

Try / catch

try {
    byte[] enc = RSACrypto.encryptAesKey(aesKey);
} catch (CryptoException e) {
    // regenerate key pair and retry once; surface persistent keystore errors
}

Prevention

When it happens

Trigger: Calling encryptAesKey (or encrypt via AESCrypto in RSA mode) before generating the RSA key pair, or when keystore access fails (provider error, keystore corrupted).

Common situations: First run where key generation was skipped; crypto initialized with RSA mode but keys never provisioned; AndroidKeyStore failures after system update or locked/limited device profile.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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