shwenzhang/AndResGuard · error · java.lang.RuntimeException
private key is not a DSA or RSA key
Error message
private key is not a DSA or RSA key
What it means
This RuntimeException is thrown by getSignatureAlgorithm when the private key loaded from the keystore has an algorithm other than DSA, RSA, or EC. The library builds a jarsigner signature algorithm string (e.g. 'SHA1withRSA') from the key algorithm and only supports those three; any other key type (or an unrecognizable algorithm name) makes it impossible to construct a valid v1 signing algorithm, so it fails fast.
Solutions
- Regenerate or export the signing key as RSA (keytool -genkeypair -keyalg RSA) and update the keystore used by AndResGuard
- Switch to v2/v3 signing (buildApkWithV2V3Sign path), which uses apksigner and does not depend on this algorithm whitelist
- Check the actual algorithm of the alias with keytool -list -keystore your.keystore and confirm it is RSA/DSA/EC
- If the key is EC but reported under another name, patch/rebuild with support for that algorithm string
Example fix
// before: EC key named 'ECDSA' or Ed25519 key in keystore // after: regenerate an RSA key keytool -genkeypair -v -keystore release.keystore -alias appkey \ -keyalg RSA -keysize 2048 -validity 10000
Defensive patterns
Strategy: validation
Validate before calling
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
try (FileInputStream in = new FileInputStream(sigFile)) { ks.load(in, storePass.toCharArray()); }
Key key = ks.getKey(alias, keyPass.toCharArray());
String alg = key == null ? null : key.getAlgorithm();
boolean ok = alg != null && (alg.equalsIgnoreCase("RSA") || alg.equalsIgnoreCase("DSA") || alg.equalsIgnoreCase("EC"));
if (!ok) throw new IllegalStateException("Keystore alias '" + alias + "' key algorithm not supported for v1 signing: " + alg); Type guard
boolean isSupportedSigningKey(java.security.Key k) {
if (k == null) return false;
String a = k.getAlgorithm();
return "RSA".equalsIgnoreCase(a) || "DSA".equalsIgnoreCase(a) || "EC".equalsIgnoreCase(a);
} Prevention
- Generate release keys with -keyalg RSA (default, most compatible)
- Inspect keystore aliases with keytool -list before wiring up signing config
- Prefer v2/v3 signing (apksigner) for modern keys; use v1 only with RSA/DSA keys
When it happens
Trigger: Calling buildApkWithV1sign with a keystore whose alias resolves to a private key whose getAlgorithm() is not DSA/RSA/EC — e.g. an Elliptic Curve key stored under a non-standard name, a HSM/PKCS11 key, or a key with an unusual algorithm identifier.
Common situations: Signing with a modern keystore generated with exotic key algorithms (e.g. Ed25519, X25519, or P-384 keys reported under names other than 'EC'); using a hardware-backed or PKCS12 entry whose algorithm string differs from what the JCE reports; switching to a new release keystore that is not RSA.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- No keystore passwords
- No key passwords
- Can't Generate signed APK. Plz check your v1sign info is…
- Can't Generate signed APK v2. Plz check your v2sign info is…
- Can not found any signed apk file
AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12).
Data as JSON: /api/errors/02a6b0cd25d66cae.
Report an issue: GitHub.
Appendix: source
Thrown at AndResGuard-core/src/main/java/com/tencent/mm/androlib/ResourceApkBuilder.java:186
private String getSignatureAlgorithm(String hash) throws Exception {
String signatureAlgorithm;
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
FileInputStream fileIn = new FileInputStream(config.mSignatureFile);
keyStore.load(fileIn, config.mStorePass.toCharArray());
Key key = keyStore.getKey(config.mStoreAlias, config.mKeyPass.toCharArray());
if (key == null) {
throw new RuntimeException("Can't get private key, please check if storepass storealias and keypass are correct");
}
String keyAlgorithm = key.getAlgorithm();
hash = formatHashAlgorithName(hash);
if (keyAlgorithm.equalsIgnoreCase("DSA")) {
keyAlgorithm = "DSA";
} else if (keyAlgorithm.equalsIgnoreCase("RSA")) {
keyAlgorithm = "RSA";
} else if (keyAlgorithm.equalsIgnoreCase("EC")) {
keyAlgorithm = "ECDSA";
} else {
throw new RuntimeException("private key is not a DSA or RSA key");
}
signatureAlgorithm = String.format("%swith%s", hash, keyAlgorithm);
return signatureAlgorithm;
}
private String formatHashAlgorithName(String hash) {
return hash.replace("-", "");
}
private void signApkV1(File unSignedApk, File signedApk) throws IOException, InterruptedException {
if (config.mUseSignAPK) {
System.out.printf("signing apk: %s\n", signedApk.getName());
if (signedApk.exists()) {
signedApk.delete();
}
signWithV1sign(unSignedApk, signedApk);
if (!signedApk.exists()) {
throw new IOException("Can't Generate signed APK. Plz check your v1sign info is correct.");View on GitHub (pinned to e4df245d82)