MuntashirAkon/AppManager · error · InvalidKeyException

Stream does not appear to be a properly formatted DSA key

Error message

Stream does not appear to be a properly formatted DSA key

What it means

generatePrivateKey recognized DSA format and ASN.1-parsed the key, but fewer than 5 integers were recovered (a DSA private key needs version, x, p, q, g), so it throws InvalidKeyException "Stream does not appear to be a properly formatted DSA key".

Source

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

                    throw new InvalidKeyException("Stream does not appear to be a properly formatted RSA key.");
                }
                BigInteger publicExponent = rsaIntegers.get(2);
                BigInteger privateExponent = rsaIntegers.get(3);
                BigInteger modulus = rsaIntegers.get(1);
                BigInteger primeP = rsaIntegers.get(4);
                BigInteger primeQ = rsaIntegers.get(5);
                BigInteger primeExponentP = rsaIntegers.get(6);
                BigInteger primeExponentQ = rsaIntegers.get(7);
                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() +

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Validate the key: openssl dsa -in dsa.pem -check -noout; re-export if corrupt.
  2. Convert to PKCS#8 PEM so the RSA/PKCS#8 path handles it: openssl pkcs8 -topk8 -nocrypt -in dsa.pem -out dsa_pkcs8.pem.
  3. Confirm the file actually contains a DSA key (openssl pkey -in key.pem -text -noout) and matches its header.
  4. Re-copy the key file without line-wrapping or whitespace corruption.

Example fix

// before
PrivateKey pk = KeyStoreUtils.generatePrivateKey(cr.openInputStream(truncatedDsaKeyUri));
// after
// validate/regenerate first: openssl dsa -in dsa.pem -check -noout
PrivateKey pk = KeyStoreUtils.generatePrivateKey(cr.openInputStream(validDsaKeyUri));
Defensive patterns

Strategy: validation

Validate before calling

// confirm DSA content matches the DSA header before parsing
String pem = readAll(is);
if (!pem.contains("-----BEGIN DSA PRIVATE KEY-----")) {
    throw new IllegalArgumentException("Expected DSA PEM input");
}
// validate with: openssl dsa -in dsa.pem -check -noout  (must succeed)

Try / catch

// try
try {
    PrivateKey pk = KeyStoreUtils.generatePrivateKey(dsaKeyIs);
} catch (InvalidKeyException e) {
    if (e.getMessage().contains("properly formatted DSA key")) {
        // truncated/mislabeled DSA data: re-export the key and retry
        retryWithReExportedKey();
    }
}

Prevention

When it happens

Trigger: Calling generatePrivateKey with truncated/malformed DSA ASN.1 data, or a non-DSA key (RSA/EC) routed into the DSA parsing branch, or corrupted base64 decoding of the DER body.

Common situations: Corrupted or truncated DSA key export; wrong header markers (e.g. BEGIN DSA PRIVATE KEY containing RSA content); copy/paste losing base64 lines; obsolete DSA keys rejected by newer openssl exports.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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