shwenzhang/AndResGuard · error · java.lang.RuntimeException

Can't get private key, please check if storepass storealias…

Error message

Can't get private key, please check if storepass storealias and keypass are correct

What it means

Before V1 signing, AndResGuard loads the keystore and calls KeyStore.getKey(alias, keyPass) to retrieve the private key. This RuntimeException is thrown when that call returns null, meaning the combination of store password, alias, and key password does not resolve to an existing key entry in the keystore.

Solutions

  1. List actual aliases: keytool -list -keystore keystore.jks -storepass xxx, and use an exact alias in sign.alias
  2. Ensure sign.keypass matches the key's password (for PKCS12 keystores it must equal storepass)
  3. Confirm the keystore entry contains a PrivateKeyEntry, not a TrustedCertificateEntry
  4. Point sign.path at the real keystore file rather than a certificate
  5. Regenerate or re-import a key if the keystore genuinely lacks a private key

Example fix

// before
sign = {
  path = 'release.jks'
  storepass = 'storePass'
  alias = 'My Alias'
  keypass = 'storePass'
}
// after (alias exactly as listed by keytool -list)
sign = {
  path = 'release.jks'
  storepass = 'storePass'
  alias = 'my_alias'
  keypass = 'keyPass'
}
Defensive patterns

Strategy: try-catch

Validate before calling

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
try (FileInputStream in = new FileInputStream(signPath)) {
  ks.load(in, storePass.toCharArray());
}
if (ks.getKey(alias, keyPass.toCharArray()) == null) {
  throw new IllegalArgumentException("No private key for alias '" + alias + "'; check storepass/alias/keypass");
}

Try / catch

try {
  resourceApkBuilder.signWithV1sign();
} catch (RuntimeException e) {
  if (e.getMessage().contains("Can't get private key")) {
    // run: keytool -list -keystore <path> -storepass <storepass>
    // verify alias and keypass, then retry with corrected config
  }
  throw e;
}

Prevention

When it happens

Trigger: config.mSignatureFile loaded successfully (storepass OK) but keyStore.getKey(mStoreAlias, mKeyPass) returned null: wrong alias name, wrong keypass, or the entry is a trusted certificate without a private key.

Common situations: Alias typo or different case; keystore where key password differs from store password (PKCS12 usually makes them identical); providing a .cer/.pem certificate file instead of a real keystore; keystore regenerated and alias changed.

Related errors


AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12). Data as JSON: /api/errors/ee67d07cf9c93f92. Report an issue: GitHub.

Appendix: source

Thrown at AndResGuard-core/src/main/java/com/tencent/mm/androlib/ResourceApkBuilder.java:175

    addStoredFileIn7Zip(storedFiles, outputAPK);
    if (!outputAPK.exists()) {
      throw new IOException(String.format(
          "[use7zApk]7z repackage signed apk fail,you must install 7z command line version first, linux: p7zip, window: 7za, path=%s",
          mSignedWith7ZipApk.getAbsolutePath()
      ));
    }
    return true;
  }

  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("-", "");

View on GitHub (pinned to e4df245d82)