MuntashirAkon/AppManager · error · NoSuchAlgorithmException

Couldn't find any suitable algorithm

Error message

Couldn't find any suitable algorithm

What it means

generatePrivateKey falls through to its final else branch when the input matched none of the supported key formats (PKCS#8, RSA PKCS#1, DSA), throwing NoSuchAlgorithmException "Couldn't find any suitable algorithm". The library only supports these private key formats, and the stream matched none.

Solutions

  1. Convert the key to PKCS#8 PEM: openssl pkcs8 -topk8 -nocrypt -in key -out key_pkcs8.pem.
  2. Convert OpenSSH-format keys: ssh-keygen -p -m PEM -f id_rsa (use an RSA key, not ed25519/EC).
  3. Generate an RSA key if using EC/ed25519, since EC keys aren't supported by this parser.
  4. Extract the private key from containers (e.g. openssl pkcs12 -in cert.p12 -nodes -nocerts) before passing it.

Example fix

// before
PrivateKey pk = KeyStoreUtils.generatePrivateKey(cr.openInputStream(ed25519KeyUri)); // unsupported
// after
// generate a supported key: ssh-keygen -t rsa -b 4096 -m PEM -f id_rsa
PrivateKey pk = KeyStoreUtils.generatePrivateKey(cr.openInputStream(rsaPemKeyUri));
Defensive patterns

Strategy: validation

Validate before calling

// only feed supported PEM formats (PKCS#8 / RSA / DSA private keys)
String pem = readAll(is);
boolean supported = pem.contains("-----BEGIN PRIVATE KEY-----")
        || pem.contains("-----BEGIN RSA PRIVATE KEY-----")
        || pem.contains("-----BEGIN DSA PRIVATE KEY-----");
if (!supported) {
    throw new IllegalArgumentException("Unsupported key format — convert to PKCS#8 PEM first");
}

Type guard

boolean isSupportedPemFormat(InputStream is) throws IOException {
    String s = readAll(is);
    return s.contains("-----BEGIN PRIVATE KEY-----")
        || s.contains("-----BEGIN RSA PRIVATE KEY-----")
        || s.contains("-----BEGIN DSA PRIVATE KEY-----");
}

Try / catch

// try
try {
    PrivateKey pk = KeyStoreUtils.generatePrivateKey(keyIs);
} catch (NoSuchAlgorithmException e) {
    if (e.getMessage().contains("Couldn't find any suitable algorithm")) {
        // unsupported format (EC/OpenSSH/PPK): convert to RSA PKCS#8 PEM and retry
        retryWith(convertToPkcs8RsaPem(keyFile));
    }
}

Prevention

When it happens

Trigger: Calling generatePrivateKey with a private key in an unsupported format: OpenSSH new format, EC keys (BEGIN EC PRIVATE KEY), PKCS#12 containers, PuTTY PPK, XML/Java JKS-exported keys, or unrecognizable headers.

Common situations: Users exporting modern EC or OpenSSH-format keys (ssh-keygen default since OpenSSH 7.8) instead of PEM RSA/DSA keys; submitting a keystore container (JKS/PKCS#12) instead of a bare key file.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/crypto/ks/KeyStoreUtils.java:283

                BigInteger crtCoefficient = rsaIntegers.get(8);
                //spec = new RSAPrivateKeySpec(modulus, privateExponent);
                spec = new RSAPrivateCrtKeySpec(modulus, publicExponent, privateExponent,
                        primeP, primeQ, primeExponentP, primeExponentQ, crtCoefficient);
            } else if (dsaFormat) {
                kf = KeyFactory.getInstance("DSA");
                List<BigInteger> dsaIntegers = new ArrayList<>();
                ASN1Parse(bytes, dsaIntegers);
                if (dsaIntegers.size() < 5) {
                    throw new InvalidKeyException("Stream does not appear to be a properly formatted DSA key");
                }
                BigInteger privateExponent = dsaIntegers.get(1);
                BigInteger publicExponent = dsaIntegers.get(2);
                BigInteger P = dsaIntegers.get(3);
                BigInteger Q = dsaIntegers.get(4);
                BigInteger G = dsaIntegers.get(5);
                spec = new DSAPrivateKeySpec(privateExponent, P, Q, G);
            } else {
                throw new NoSuchAlgorithmException("Couldn't find any suitable algorithm");
            }
            return kf.generatePrivate(spec);
        }
    }

    public static byte[] getPemCertificate(@NonNull Certificate certificate)
            throws CertificateEncodingException, IOException {
        BASE64Encoder encoder = new BASE64Encoder();
        try (ByteArrayOutputStream os = new ByteArrayOutputStream(X509Factory.BEGIN_CERT.length() +
                X509Factory.BEGIN_CERT.length() + certificate.getEncoded().length + 2)) {
            os.write(X509Factory.BEGIN_CERT.getBytes(StandardCharsets.UTF_8));
            os.write('\n');
            encoder.encode(certificate.getEncoded(), os);
            os.write('\n');
            os.write(X509Factory.END_CERT.getBytes(StandardCharsets.UTF_8));
            return os.toByteArray();
        }
    }

View on GitHub (pinned to 0152f468fc)