Support custom keystore

This commit is contained in:
Nullptr 2022-03-27 16:59:42 +08:00
parent 7905b343dc
commit 02d6752895
1 changed files with 40 additions and 25 deletions

View File

@ -13,6 +13,7 @@ import com.android.tools.build.apkzlib.zip.ZFile;
import com.android.tools.build.apkzlib.zip.ZFileOptions; import com.android.tools.build.apkzlib.zip.ZFileOptions;
import com.beust.jcommander.JCommander; import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterException;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.wind.meditor.core.ManifestEditor; import com.wind.meditor.core.ManifestEditor;
import com.wind.meditor.property.AttributeItem; import com.wind.meditor.property.AttributeItem;
@ -72,6 +73,9 @@ public class LSPatch {
@Parameter(names = {"-l", "--sigbypasslv"}, description = "Signature bypass level. 0 (disable), 1 (pm), 2 (pm+openat). default 0") @Parameter(names = {"-l", "--sigbypasslv"}, description = "Signature bypass level. 0 (disable), 1 (pm), 2 (pm+openat). default 0")
private int sigbypassLevel = 0; private int sigbypassLevel = 0;
@Parameter(names = {"-k", "--keystore"}, arity = 4, description = "Set custom signature keystore. Followed by 4 arguments: keystore path, keystore password, keystore alias, keystore alias password")
private List<String> keystoreArgs = Arrays.asList(null, "123456", "key0", "123456");
@Parameter(names = {"--v1"}, arity = 1, description = "Sign with v1 signature") @Parameter(names = {"--v1"}, arity = 1, description = "Sign with v1 signature")
private boolean v1 = false; private boolean v1 = false;
@ -117,38 +121,40 @@ public class LSPatch {
private final Logger logger; private final Logger logger;
public LSPatch(Logger logger, String... args) { public LSPatch(Logger logger, String... args) {
jCommander = JCommander.newBuilder() jCommander = JCommander.newBuilder().addObject(this).build();
.addObject(this) try {
.build(); jCommander.parse(args);
jCommander.parse(args); } catch (ParameterException e) {
logger.e(e.getMessage() + "\n");
help = true;
}
if (apkPaths == null || apkPaths.isEmpty()) {
logger.e("No apk specified\n");
help = true;
}
if (!modules.isEmpty() && useManager) {
logger.e("Should not use --embed and --manager at the same time\n");
help = true;
}
this.logger = logger; this.logger = logger;
logger.verbose = verbose; logger.verbose = verbose;
} }
public static void main(String... args) throws IOException { public static void main(String... args) throws IOException {
LSPatch lsPatch = new LSPatch(new JavaLogger(), args); LSPatch lspatch = new LSPatch(new JavaLogger(), args);
if (lspatch.help) {
lspatch.jCommander.usage();
return;
}
try { try {
lsPatch.doCommandLine(); lspatch.doCommandLine();
} catch (PatchError e) { } catch (PatchError e) {
e.printStackTrace(System.err); e.printStackTrace(System.err);
} }
} }
public void doCommandLine() throws PatchError, IOException { public void doCommandLine() throws PatchError, IOException {
if (help) {
jCommander.usage();
return;
}
if (apkPaths == null || apkPaths.isEmpty()) {
jCommander.usage();
return;
}
if (!modules.isEmpty() && useManager) {
jCommander.usage();
return;
}
for (var apk : apkPaths) { for (var apk : apkPaths) {
File srcApkFile = new File(apk).getAbsoluteFile(); File srcApkFile = new File(apk).getAbsoluteFile();
@ -181,13 +187,20 @@ public class LSPatch {
var srcZFile = dstZFile.addNestedZip((ignore) -> ORIGINAL_APK_ASSET_PATH, srcApkFile, false)) { var srcZFile = dstZFile.addNestedZip((ignore) -> ORIGINAL_APK_ASSET_PATH, srcApkFile, false)) {
// sign apk // sign apk
logger.i("Register apk signer...");
try { try {
var keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); var keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
try (var is = getClass().getClassLoader().getResourceAsStream("assets/keystore")) { if (keystoreArgs.get(0) == null) {
keyStore.load(is, "123456".toCharArray()); logger.i("Register apk signer with default keystore...");
try (var is = getClass().getClassLoader().getResourceAsStream("assets/keystore")) {
keyStore.load(is, keystoreArgs.get(1).toCharArray());
}
} else {
logger.i("Register apk signer with custom keystore...");
try (var is = new FileInputStream(keystoreArgs.get(0))) {
keyStore.load(is, keystoreArgs.get(1).toCharArray());
}
} }
var entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry("key0", new KeyStore.PasswordProtection("123456".toCharArray())); var entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(keystoreArgs.get(2), new KeyStore.PasswordProtection(keystoreArgs.get(3).toCharArray()));
new SigningExtension(SigningOptions.builder() new SigningExtension(SigningOptions.builder()
.setMinSdkVersion(28) .setMinSdkVersion(28)
.setV1SigningEnabled(v1) .setV1SigningEnabled(v1)
@ -292,7 +305,9 @@ public class LSPatch {
return false; return false;
}); });
embedModules(dstZFile); if (!useManager) {
embedModules(dstZFile);
}
// create zip link // create zip link
logger.d("Creating nested apk link..."); logger.d("Creating nested apk link...");