use of com.android.apksig.ApkSigner in project AndResGuard by shwenzhang.
the class ApkSignerTool method sign.
private static void sign(String[] params) throws Exception {
if (params.length == 0) {
printUsage(HELP_PAGE_SIGN);
return;
}
File outputApk = null;
File inputApk = null;
boolean verbose = false;
boolean v1SigningEnabled = true;
boolean v2SigningEnabled = true;
int minSdkVersion = 1;
boolean minSdkVersionSpecified = false;
int maxSdkVersion = Integer.MAX_VALUE;
List<SignerParams> signers = new ArrayList<>(1);
SignerParams signerParams = new SignerParams();
OptionsParser optionsParser = new OptionsParser(params);
String optionName;
String optionOriginalForm = null;
while ((optionName = optionsParser.nextOption()) != null) {
optionOriginalForm = optionsParser.getOptionOriginalForm();
if (("help".equals(optionName)) || ("h".equals(optionName))) {
printUsage(HELP_PAGE_SIGN);
return;
} else if ("out".equals(optionName)) {
outputApk = new File(optionsParser.getRequiredValue("Output file name"));
} else if ("in".equals(optionName)) {
inputApk = new File(optionsParser.getRequiredValue("Input file name"));
} else if ("min-sdk-version".equals(optionName)) {
minSdkVersion = optionsParser.getRequiredIntValue("Mininimum API Level");
minSdkVersionSpecified = true;
} else if ("max-sdk-version".equals(optionName)) {
maxSdkVersion = optionsParser.getRequiredIntValue("Maximum API Level");
} else if ("v1-signing-enabled".equals(optionName)) {
v1SigningEnabled = optionsParser.getOptionalBooleanValue(true);
} else if ("v2-signing-enabled".equals(optionName)) {
v2SigningEnabled = optionsParser.getOptionalBooleanValue(true);
} else if ("next-signer".equals(optionName)) {
if (!signerParams.isEmpty()) {
signers.add(signerParams);
signerParams = new SignerParams();
}
} else if ("ks".equals(optionName)) {
signerParams.keystoreFile = optionsParser.getRequiredValue("KeyStore file");
} else if ("ks-key-alias".equals(optionName)) {
signerParams.keystoreKeyAlias = optionsParser.getRequiredValue("KeyStore key alias");
} else if ("ks-pass".equals(optionName)) {
signerParams.keystorePasswordSpec = optionsParser.getRequiredValue("KeyStore password");
} else if ("key-pass".equals(optionName)) {
signerParams.keyPasswordSpec = optionsParser.getRequiredValue("Key password");
} else if ("v1-signer-name".equals(optionName)) {
signerParams.v1SigFileBasename = optionsParser.getRequiredValue("JAR signature file basename");
} else if ("ks-type".equals(optionName)) {
signerParams.keystoreType = optionsParser.getRequiredValue("KeyStore type");
} else if ("ks-provider-name".equals(optionName)) {
signerParams.keystoreProviderName = optionsParser.getRequiredValue("JCA KeyStore Provider name");
} else if ("ks-provider-class".equals(optionName)) {
signerParams.keystoreProviderClass = optionsParser.getRequiredValue("JCA KeyStore Provider class name");
} else if ("ks-provider-arg".equals(optionName)) {
signerParams.keystoreProviderArg = optionsParser.getRequiredValue("JCA KeyStore Provider constructor argument");
} else if ("key".equals(optionName)) {
signerParams.keyFile = optionsParser.getRequiredValue("Private key file");
} else if ("cert".equals(optionName)) {
signerParams.certFile = optionsParser.getRequiredValue("Certificate file");
} else if (("v".equals(optionName)) || ("verbose".equals(optionName))) {
verbose = optionsParser.getOptionalBooleanValue(true);
} else {
throw new ParameterException("Unsupported option: " + optionOriginalForm + ". See --help for supported" + " options.");
}
}
if (!signerParams.isEmpty()) {
signers.add(signerParams);
}
signerParams = null;
if (signers.isEmpty()) {
throw new ParameterException("At least one signer must be specified");
}
params = optionsParser.getRemainingParams();
if (inputApk != null) {
// parameters.
if (params.length > 0) {
throw new ParameterException("Unexpected parameter(s) after " + optionOriginalForm + ": " + params[0]);
}
} else {
// supposed to be the path to input APK.
if (params.length < 1) {
throw new ParameterException("Missing input APK");
} else if (params.length > 1) {
throw new ParameterException("Unexpected parameter(s) after input APK (" + params[1] + ")");
}
inputApk = new File(params[0]);
}
if ((minSdkVersionSpecified) && (minSdkVersion > maxSdkVersion)) {
throw new ParameterException("Min API Level (" + minSdkVersion + ") > max API Level (" + maxSdkVersion + ")");
}
List<ApkSigner.SignerConfig> signerConfigs = new ArrayList<>(signers.size());
int signerNumber = 0;
try (PasswordRetriever passwordRetriever = new PasswordRetriever()) {
for (SignerParams signer : signers) {
signerNumber++;
signer.name = "signer #" + signerNumber;
try {
signer.loadPrivateKeyAndCerts(passwordRetriever);
} catch (ParameterException e) {
System.err.println("Failed to load signer \"" + signer.name + "\": " + e.getMessage());
System.exit(2);
return;
} catch (Exception e) {
System.err.println("Failed to load signer \"" + signer.name + "\"");
e.printStackTrace();
System.exit(2);
return;
}
String v1SigBasename;
if (signer.v1SigFileBasename != null) {
v1SigBasename = signer.v1SigFileBasename;
} else if (signer.keystoreKeyAlias != null) {
v1SigBasename = signer.keystoreKeyAlias;
} else if (signer.keyFile != null) {
String keyFileName = new File(signer.keyFile).getName();
int delimiterIndex = keyFileName.indexOf('.');
if (delimiterIndex == -1) {
v1SigBasename = keyFileName;
} else {
v1SigBasename = keyFileName.substring(0, delimiterIndex);
}
} else {
throw new RuntimeException("Neither KeyStore key alias nor private key file available");
}
ApkSigner.SignerConfig signerConfig = new ApkSigner.SignerConfig.Builder(v1SigBasename, signer.privateKey, signer.certs).build();
signerConfigs.add(signerConfig);
}
}
if (outputApk == null) {
outputApk = inputApk;
}
File tmpOutputApk;
if (inputApk.getCanonicalPath().equals(outputApk.getCanonicalPath())) {
tmpOutputApk = File.createTempFile("apksigner", ".apk");
tmpOutputApk.deleteOnExit();
} else {
tmpOutputApk = outputApk;
}
ApkSigner.Builder apkSignerBuilder = new ApkSigner.Builder(signerConfigs).setInputApk(inputApk).setOutputApk(tmpOutputApk).setOtherSignersSignaturesPreserved(false).setV1SigningEnabled(v1SigningEnabled).setV2SigningEnabled(v2SigningEnabled);
if (minSdkVersionSpecified) {
apkSignerBuilder.setMinSdkVersion(minSdkVersion);
}
ApkSigner apkSigner = apkSignerBuilder.build();
try {
apkSigner.sign();
} catch (MinSdkVersionException e) {
String msg = e.getMessage();
if (!msg.endsWith(".")) {
msg += '.';
}
throw new MinSdkVersionException("Failed to determine APK's minimum supported platform version" + ". Use --min-sdk-version to override", e);
}
if (!tmpOutputApk.getCanonicalPath().equals(outputApk.getCanonicalPath())) {
Files.move(tmpOutputApk.toPath(), outputApk.toPath(), StandardCopyOption.REPLACE_EXISTING);
}
if (verbose) {
System.out.println("Signed");
}
}
Aggregations