Coder Social home page Coder Social logo

patrickfav / uber-apk-signer Goto Github PK

View Code? Open in Web Editor NEW
1.8K 33.0 182.0 7.76 MB

A cli tool that helps signing and zip aligning single or multiple Android application packages (APKs) with either debug or provided release certificates. It supports v1, v2 and v3 Android signing scheme has an embedded debug keystore and auto verifies after signing.

Home Page: https://favr.dev/opensource/uber-apk-signer

License: Apache License 2.0

Java 100.00%
apk signing zipalign keystore signature android cli verify android-signing-scheme apksigner

uber-apk-signer's Introduction

Uber Apk Signer

A tool that helps to sign, zip aligning and verifying multiple Android application packages (APKs) with either debug or provided release certificates (or multiple). It supports v1, v2, v3 Android signing scheme and v4 Android signing scheme. Easy and convenient debug signing with embedded debug keystore. Automatically verifies signature and zipalign after every signing.

GitHub release Github Actions Coverage Maintainability Rating

Main features:

  • zipalign, (re)signing and verifying of multiple APKs in one step
  • verify signature (with hash check) and zipalign of multiple APKs in one step
  • built-in zipalign & debug keystore for convenient usage
  • supports v1, v2, v3 and v4 android apk singing scheme
  • support for multiple signatures for one APK
  • crypto/signing code relied upon official implementation

Basic usage:

java -jar uber-apk-signer.jar --apks /path/to/apks

This should run on any Windows, Mac or Linux machine where JDK8 is installed.

Requirements

  • JDK 8
  • Currently on Linux 32bit: zipalign must be set in PATH

Download

Grab jar from the latest Release

Demo

asciicast

Command Line Interface

-a,--apks <file/folder>           Can be a single apk or a folder containing multiple apks. These are used
                                  as source for zipalining/signing/verifying. It is also possible to
                                  provide multiple locations space seperated (can be mixed file folder):
                                  '/apk /apks2 my.apk'. Folder will be checked non-recursively.
   --allowResign                  If this flag is set, the tool will not show error on signed apks, but
                                  will sign them with the new certificate (therefore removing the old
                                  one).
   --debug                        Prints additional info for debugging.
   --dryRun                       Check what apks would be processed without actually doing anything.
-h,--help                         Prints help docs.
   --ks <keystore>                The keystore file. If this isn't provided, will tryto sign with a debug
                                  keystore. The debug keystore will be searched in the same dir as
                                  execution and 'user_home/.android' folder. If it is not found there a
                                  built-in keystore will be used for convenience. It is possible to pass
                                  one or multiple keystores. The syntax for multiple params is
                                  '<index>=<keystore>' for example: '1=keystore.jks'. Must match the
                                  parameters of --ksAlias.
   --ksAlias <alias>              The alias of the used key in the keystore. Must be provided if --ks is
                                  provided. It is possible to pass one or multiple aliases for multiple
                                  keystore configs. The syntax for multiple params is '<index>=<alias>'
                                  for example: '1=my-alias'. Must match the parameters of --ks.
   --ksDebug <keystore>           Same as --ks parameter but with a debug keystore. With this option the
                                  default keystore alias and passwords are used and any arguments relating
                                  to these parameter are ignored.
   --ksKeyPass <password>         The password for the key. If this is not provided, caller will get a
                                  user prompt to enter it. It is possible to pass one or multiple
                                  passwords for multiple keystore configs. The syntax for multiple params
                                  is '<index>=<password>'. Must match the parameters of --ks.
   --ksPass <password>            The password for the keystore. If this is not provided, caller will get
                                  a user prompt to enter it. It is possible to pass one or multiple
                                  passwords for multiple keystore configs. The syntax for multiple params
                                  is '<index>=<password>'. Must match the parameters of --ks.
-l,--lineage <path>               The lineage file for apk signer schema v3 if more then 1 signature is
                                  used. See here https://bit.ly/2mh6iAC for more info.
-o,--out <path>                   Where the aligned/signed apks will be copied to. Must be a folder. Will
                                  create, if it does not exist.
   --overwrite                    Will overwrite/delete the apks in-place
   --skipZipAlign                 Skips zipAlign process. Also affects verify.
-v,--version                      Prints current version.
   --verbose                      Prints more output, especially useful for sign verify.
   --verifySha256 <cert-sha256>   Provide one or multiple sha256 in string hex representation (ignoring
                                  case) to let the tool check it against hashes of the APK's certificate
                                  and use it in the verify process. All given hashes must be present in
                                  the signature to verify e.g. if 2 hashes are given the apk must have 2
                                  signatures with exact these hashes (providing only one hash, even if it
                                  matches one cert, will fail).
-y,--onlyVerify                   If this is passed, the signature and alignment is only verified.
   --zipAlignPath <path>          Pass your own zipalign executable. If this is omitted the built-in
                                  version is used (available for win, mac and linux)

Examples

Provide your own out directory for signed apks

java -jar uber-apk-signer.jar -a /path/to/apks --out /path/to/apks/out

Only verify the signed apks

java -jar uber-apk-signer.jar -a /path/to/apks --onlyVerify

Sign with your own release keystore

java -jar uber-apk-signer.jar -a /path/to/apks --ks /path/release.jks --ksAlias my_alias

Provide your own zipalign executable

java -jar uber-apk-signer.jar -a /path/to/apks --zipAlignPath /sdk/build-tools/24.0.3/zipalign

Provide your own location of your debug keystore

java -jar uber-apk-signer.jar -a /path/to/apks --ksDebug /path/debug.jks

Sign with your multiple release keystores (see below on how to create a lineage file)

java -jar uber-apk-signer.jar -a /path/to/apks --lineage /path/sig.lineage --ks 1=/path/release.jks 2=/path/release2.jks --ksAlias 1=my_alias1 2=my_alias2

Use multiple locations or files (will ignore duplicate files)

java -jar uber-apk-signer.jar -a /path/to/apks /path2 /path3/select1.apk /path3/select2.apk

Provide your sha256 hash to check against the signature:

java -jar uber-apk-signer.jar -a /path/to/apks --onlyVerify --verifySha256 ab318df27

Process Return Value

This application will return 0 if every signing/verifying was successful, 1 if an error happens (e.g. wrong arguments) and 2 if at least 1 sign/verify process was not successful.

Debug Signing Mode

If no keystore is provided the tool will try to automatically sign with a debug keystore. It will try to find on in the following locations (descending order):

  • Keystore location provided with --ksDebug
  • debug.keystore in the same directory as the jar executable
  • debug.keystore found in the /user_home/.android folder
  • Embedded debug.keystore packaged with the jar executable

A log message will indicate which one was chosen.

Zipalign Executable

Zipalign is a tool developed by Google to optimize zips (apks). It is needed if you want to upload it to the Playstore otherwise it is optional. By default, this tool will try to zipalign the apk, therefore it will need the location of the executable. If the path isn't passed in the command line interface, the tool checks if it is in PATH environment variable, otherwise it will try to use an embedded version of zipalign.

If --skipZipAlign is passed no executable is needed.

v1, v2 and v3 Signing Scheme

Android 7.0 introduces APK Signature Scheme v2, a new app-signing scheme that offers faster app install times and more protection against unauthorized alterations to APK files. By default, Android Studio 2.2 and the Android Plugin for Gradle 2.2 sign your app using both APK Signature Scheme v2 and the traditional signing scheme, which uses JAR signing.

APK Signature Scheme v2 is a whole-file signature scheme that increases verification speed and strengthens integrity guarantees by detecting any changes to the protected parts of the APK. The older jarsigning is called v1 schema.

APK Signature Scheme v3 is an extension to v2 which allows a new signature lineage feature for key rotation, which basically means it will be possible to change signature keys.

Signature Lineage File in Schema v3

This tool does not directly support the creation of lineage files as it is considered a task done very rarely. You can create a lineage file with a sequence of certificates with Google's apksigner rotate and apply it as -- lineage arguments when signing with multiple keystores:

apksigner rotate --out sig.lineage \
    --old-signer --ks debug1.keystore --ks-key-alias androiddebugkey \
    --new-signer --ks debug2.keystore --ks-key-alias androiddebugkey

java -jar uber-apk-signer.jar -a /path/to/apks --lineage sig.lineage (...)

Signed Release Jar

The provided JARs in the GitHub release page are signed with my private key:

CN=Patrick Favre-Bulle, OU=Private, O=PF Github Open Source, L=Vienna, ST=Vienna, C=AT
Validity: Thu Sep 07 16:40:57 SGT 2017 to: Fri Feb 10 16:40:57 SGT 2034
SHA1: 06:DE:F2:C5:F7:BC:0C:11:ED:35:E2:0F:B1:9F:78:99:0F:BE:43:C4
SHA256: 2B:65:33:B0:1C:0D:2A:69:4E:2D:53:8F:29:D5:6C:D6:87:AF:06:42:1F:1A:EE:B3:3C:E0:6D:0B:65:A1:AA:88

Use the jarsigner tool (found in your $JAVA_HOME/bin folder) folder to verify.

Build with Maven

Use the Maven wrapper to create a jar including all dependencies

./mvnw clean install

Checkstyle Config File

This project uses my common-parent which centralized a lot of the plugin versions as well as providing the checkstyle config rules. Specifically they are maintained in checkstyle-config. Locally the files will be copied after you mvnw install into your target folder and is called target/checkstyle-checker.xml. So if you use a plugin for your IDE, use this file as your local configuration.

Tech-Stack

  • Java 8
  • Maven

License

Copyright 2016 Patrick Favre-Bulle

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

uber-apk-signer's People

Contributors

dependabot[bot] avatar patrickfav avatar subho007 avatar yihongyuelan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uber-apk-signer's Issues

External zipalign conflicts W/ embedded zipalign | 64bit + 32bit Linux

G'day @patrickfav, sorry to bother you mate, but I've been coming across this issue for a while now, and I've only just managed to figure why the problem was arising today.

a problem I've noticed is that when the user installs zipalign from the Command Line using package management tools such as apt or pacman, the external zipalign package in the users PATH, and the embed zipalign version that comes with Uber APK Signer, seems to conflict with each other, resulting in the error below

Error: Command failed: java -jar "/home/kali/AhMyth/AhMyth-Server/app/app/Factory/sign.jar" -a "/home/kali/AhMyth/Output/Ahmyth.apk"
Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true
could not execute zipalign
Run with '--debug' parameter to get additional information.

removing the zipalign package installed from the Command Line allows the signer to run it's embedded version of zipalign which fixes the problem, However if a path to a zipalign executable is not explicitly specified, then it should use the package version installed via the Command Line if it's available (which it should since it's automatically added to the users PATH variable at installation time), otherwise it should fall back to the embedded version if the PATH check for zipalign returns null according to the screenshot below (correct me if I'm wrong).

However both the external zipalign package and the embedded zipalign conflict with each other regardless of the external version being declared in the PATH variable

IMG_20230909_155257

The Uber APK Signer version I'm utilising is v1.2.1

Edit

Just tested the same scenario with a 32bit Kali Linux VM and the same problem happened for some reason, external zipalign conflicts with embedded zipalign unless external package is removed.

how to solve invalid keystore format error in android studio 2.2

**here is error report-------->
error:Error:java.lang.RuntimeException:

com.android.ide.common.signing.KeytoolException: Failed to read key palash from store "D:\MyApplication3\.idea\workspace.xml": Invalid keystore format
second error:Error:com.android.ide.common.signing.KeytoolException: Failed to read key palash from store "D:\MyApplication3\.idea\workspace.xml": Invalid keystore format
third error:Error:java.io.IOException: Invalid keystore format

how to solve this three errors??????**
here is gradle console message----------->

FAILURE: Build failed with an exception.

  • What went wrong:
    Execution failed for task ':app:packageRelease'.

com.android.ide.common.signing.KeytoolException: Failed to read key palash from store "D:\MyApplication3.idea\workspace.xml": Invalid keystore format

  • Try:
    Run with --info or --debug option to get more log output.

  • Exception is:
    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:packageRelease'.
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:69)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:46)
    at org.gradle.api.internal.tasks.execution.PostExecutionAnalysisTaskExecuter.execute(PostExecutionAnalysisTaskExecuter.java:35)
    at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:66)
    at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:58)
    at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
    at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:53)
    at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:203)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:185)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.processTask(AbstractTaskPlanExecutor.java:66)
    at org.gradle.execution.taskgraph.AbstractTaskPlanExecutor$TaskExecutorWorker.run(AbstractTaskPlanExecutor.java:50)
    at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:25)
    at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:110)
    at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
    at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
    at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
    at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:32)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
    at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
    at org.gradle.initialization.DefaultGradleLauncher$4.run(DefaultGradleLauncher.java:153)
    at org.gradle.internal.Factories$1.create(Factories.java:22)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:53)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:150)
    at org.gradle.initialization.DefaultGradleLauncher.access$200(DefaultGradleLauncher.java:32)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:98)
    at org.gradle.initialization.DefaultGradleLauncher$1.create(DefaultGradleLauncher.java:92)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:91)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:63)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:92)
    at org.gradle.initialization.DefaultGradleLauncher.run(DefaultGradleLauncher.java:83)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter$DefaultBuildController.run(InProcessBuildActionExecuter.java:99)
    at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:46)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:58)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:48)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:81)
    at org.gradle.launcher.exec.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:46)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:52)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.health.DaemonHealthTracker.execute(DaemonHealthTracker.java:47)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.health.HintGCAfterBuild.execute(HintGCAfterBuild.java:41)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:237)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
    Caused by: java.lang.RuntimeException: com.android.ide.common.signing.KeytoolException: Failed to read key palash from store "D:\MyApplication3.idea\workspace.xml": Invalid keystore format
    at com.android.build.gradle.tasks.PackageAndroidArtifact.doTask(PackageAndroidArtifact.java:469)
    at com.android.build.gradle.tasks.PackageAndroidArtifact.doFullTaskAction(PackageAndroidArtifact.java:321)
    at com.android.build.gradle.tasks.PackageApplication.doFullTaskAction(PackageApplication.java:75)
    at com.android.build.gradle.internal.tasks.IncrementalTask.taskAction(IncrementalTask.java:88)
    at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:75)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.doExecute(AnnotationProcessingTaskFactory.java:245)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:221)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$IncrementalTaskAction.execute(AnnotationProcessingTaskFactory.java:232)
    at org.gradle.api.internal.project.taskfactory.AnnotationProcessingTaskFactory$StandardTaskAction.execute(AnnotationProcessingTaskFactory.java:210)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:80)
    at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:61)
    ... 70 more
    Caused by: com.android.ide.common.signing.KeytoolException: Failed to read key palash from store "D:\MyApplication3.idea\workspace.xml": Invalid keystore format
    at com.android.ide.common.signing.KeystoreHelper.getCertificateInfo(KeystoreHelper.java:212)
    at com.android.build.gradle.tasks.PackageAndroidArtifact.doTask(PackageAndroidArtifact.java:431)
    ... 80 more
    Caused by: java.io.IOException: Invalid keystore format
    at com.android.ide.common.signing.KeystoreHelper.getCertificateInfo(KeystoreHelper.java:190)
    ... 81 more

BUILD FAILED

Total time: 1 mins 32.136 secs
**

Cannot verify app signed without scheme v1

01. app-release.apk

	VERIFY
	file: /path/to/OnePlusExtension/app/release/app-release.apk
	checksum: b6061010215bdcd30b2971202b465d87c12feaac3492db821d55ed59a9f38146 (sha256)
	- zipalign verified
	- signature VERIFY FAILED (app-release.apk)
		ERROR: No JAR signatures

[Mon Feb 05 09:37:39 CST 2018][v0.8.3]
Successfully processed 0 APKs and 1 errors in 0.21 seconds.

This apk can be verified successfully by nougat/oreo for it's signed with scheme v2. It should be a expected behavior that an apk signed without v1 (/META-INF/CERT.*) is also valid.

Sample package available here.

java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big.

This error is throwed and what can I do ?

Failed to load signer "signer #1"
java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big.
at java.base/sun.security.util.DerInputStream.getLength(DerInputStream.java:604)
at java.base/sun.security.util.DerValue.init(DerValue.java:385)
at java.base/sun.security.util.DerValue.(DerValue.java:327)
at java.base/sun.security.util.DerValue.(DerValue.java:340)
at java.base/sun.security.pkcs12.PKCS12KeyStore.engineLoad(PKCS12KeyStore.java:1984)
at java.base/sun.security.util.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:220)
at java.base/java.security.KeyStore.load(KeyStore.java:1472)
at com.android.apksigner.SignerParams.loadKeyStoreFromFile(SignerParams.java:362)
at com.android.apksigner.SignerParams.loadPrivateKeyAndCertsFromKeyStore(SignerParams.java:248)
at com.android.apksigner.SignerParams.loadPrivateKeyAndCerts(SignerParams.java:181)
at com.android.apksigner.ApkSignerTool.getSignerConfig(ApkSignerTool.java:419)
at com.android.apksigner.ApkSignerTool.sign(ApkSignerTool.java:336)
at com.android.apksigner.ApkSignerTool.main(ApkSignerTool.java:92)
at at.favre.tools.apksigner.SignTool.sign(SignTool.java:314)
at at.favre.tools.apksigner.SignTool.execute(SignTool.java:150)
at at.favre.tools.apksigner.SignTool.mainExecute(SignTool.java:45)
at at.favre.tools.apksigner.SignTool.main(SignTool.java:33)

zipalign not compressing

zipalign not compressing as
(java -jar uber-apk-signer.jar -a apk/app-release-unsigned.apk --out release)

C:\cordova\Android\android-sdk\build-tools\29.0.3\zipalign -v 4 app-release-unsigned.apk appname.apk
where app-release-unsigned.apk contains 265kb when it gets compressed it gets appname.apk 258kb

can't verify signature

while trying to udate to new version .iam getting this error can't verify signature KB63363901

Any Identifiable Info & Advantage of uber-apk-signer vs Openssl?

Hello,

Is there anything when signing certs that can be identified back to the person, or computer, etc., that can identify where it comes from?

From my understanding no, it's only what information someone puts in/creates... The owner/issuer O= L= ST= C= etc...

Nice app you created too...

But in Linux I just do all this by hand, so is there really any advantage to using uber-apk-signer over signing my own in Linux like the below?

mkdir -p /etc/ssl/localcerts

Run cmds in /localcerts

openssl genrsa -out key.pem 1024
openssl req -new -key key.pem -out request.pem
openssl x509 -req -days 9999 -in request.pem -signkey key.pem -out certificate.pem
openssl pkcs8 -topk8 -outform DER -in key.pem -inform PEM -out key.pk8 -nocrypt

java -jar signapk.jar /etc/ssl/localcerts/certificate.pem /etc/ssl/localcerts/key.pk8 framework-res.apk test.apk

THANKS

Question: Adding Extensions?

Hello,

I hope you don't mind me asking, since you do all of this, I assumed you would know how I can add the
AuthorityKeyIdentifier Extension to a keystore like listed below?

keytool -printcert -file CERT.RSA
Owner: EMAILADDRESS=[email protected], CN=OnePlus, OU=SW, O=OnePlus, L=Shenzhen, ST=Guangdong, C=CN
Issuer: EMAILADDRESS=[email protected], CN=OnePlus, OU=SW, O=OnePlus, L=Shenzhen, ST=Guangdong, C=CN
Serial number: ca7f2ef3e2f1842e
Valid from: Wed May 06 21:23:23 HST 2015 until: Sun Sep 21 21:23:23 HST 2042
Certificate fingerprints:
MD5: 0D:2B:B4:93:D4:C2:58:EB:10:5F:A6:E0:D5:9A:C4:7B
SHA1: 23:52:7E:F3:0C:2E:B1:07:DC:50:D2:80:07:94:B5:D5:8E:60:67:FC
SHA256: C6:E8:15:0A:A5:BB:AF:52:3C:A1:E2:D9:E3:56:00:8E:17:28:A1:2F:E2:0C:3C:78:75:A4:46:AF:B7:C5:79:F9
Signature algorithm name: SHA1withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions:

#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: E2 4C A1 8E 47 F2 C0 74 76 F9 D3 7C E0 D8 5A 9F .L..G..tv.....Z.
0010: 2F DF 44 56 /.DV
]
]

#2: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
CA:true
PathLen:2147483647
]

#3: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: E2 4C A1 8E 47 F2 C0 74 76 F9 D3 7C E0 D8 5A 9F .L..G..tv.....Z.
0010: 2F DF 44 56 /.DV
]
]

Oracle states; . For non self-signed certificates, the authorityKeyIdentifier is always created.

I can make a keystore with the BasicConstraints, it's my understanding that the SubjectKeyIdentifier is always added.

This is what I've been playing with in a shell script, but it only adds the SubjectKeyIdentifier and BasicConstraints

Create a self signed key pair root CA certificate
keytool -genkeypair -v
-alias CERT
-dname "CN=Android, OU=Android, O=US, L=US, ST=US, C=US"
-keystore keystore.jks
-keypass android
-storepass android
-keyalg RSA
-keysize 4096
-ext BasicConstraints:"critical=ca:true"
-validity 9855

If I do all of this in a shell, then I get the AuthorityKeyIdentifier but I also get double of the same cert information, listed at the top; owner/issuer serial number, fingerprints, etc...

Create a self signed key pair root CA certificate
keytool -genkeypair -v
-alias CERT
-dname "CN=Android, OU=Android, O=US, L=US, ST=US, C=US"
-keystore keystore.jks
-keypass android
-storepass android
-keyalg RSA
-keysize 4096
-ext BasicConstraints:"critical=ca:true"
-validity 9855

Generate new ca-cert and ca-key
openssl
req
-new
-x509
-subj "/CN=Android/OU=Android/O=US/L=US/ST=US/C=US/"
-passout pass:android
-keyout ca-key
-out ca-cert
-days 9855

Extracting cert/creating cert sign req(csr)
keytool
-keystore keystore.jks
-keypass android
-storepass android
-alias CERT
-certreq
-file cert-file

Sign the “cert-file” and cert-signed wil be the new cert
openssl
x509
-req
-CA ca-cert
-CAkey ca-key
-in cert-file
-out cert-signed
-days 9855
-CAcreateserial
-passin pass:android

Importing the ca-cert to keystore file:
keytool
-keystore keystore.jks
-alias CARoot
-import
-file ca-cert
-storepass android
-noprompt

THANK YOU for your time and help with this, it's greatly appreciated, and I do like uber-apk-signer, I just like trying to learn and do this myself...

Unnecessary external com.android:apksigner dependency

pom.xml contains the system dependency

        <dependency>
            <groupId>com.android</groupId>
            <artifactId>apksigner</artifactId>
            <version>1.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/src/main/resources/lib/apksigner_33_0_2.jar</systemPath>
        </dependency>

which makes building uber-apk-signer unnecessary complicated. Google releases the library version of apksigner in it's maven repository: https://mvnrepository.com/artifact/com.android.tools.build/apksig?repo=google

So you only have to add

	<repositories>
		<repository>
			<id>Google</id>
			<name>Google</name>
			<url>https://maven.google.com/</url>
		</repository>
	</repositories>

and then use the dependency

<dependency>
    <groupId>com.android.tools.build</groupId>
    <artifactId>apksig</artifactId>
    <version>8.0.2</version>
</dependency>

You can then directly com.android.apksig.ApkSigner and com.android.apksig.ApkVerifier within your code.

android:extractNativeLibs="false"

Does it support apk files with android:extractNativeLibs="false"?
In this case also the binary libraries must be stored uncompressed and zip-aligned.

Got error result when using onlyVerify argument

$ java -jar ~/Downloads/uber-apk-signer-1.0.0.jar -a 1.apk --skipZipAlign --onlyVerify
source:
	~/Downloads

01. 1.apk

	VERIFY
	file: /1.apk (92.59 MiB)
	checksum: adf141e9285c1a3d4728298cec6c1337a9373db68155ec545cc5b48819457642 (sha256)
	- signature VERIFY FAILED (1.apk)
		ERROR: APK Signature Scheme v2 signer #1: Malformed additional attribute #1

[Fri Oct 26 17:40:02 CST 2018][v1.0.0]

but the apk could install success on my Android 5.0 & 5.1 devices.

here is my test app:

https://pan.baidu.com/s/1m7zBxvuH_EA1kI72ol7-4g

[feature request] improve error handling when input is not .apk (output/exit code)

I often sign zip, jars etc..
kind of feeded a zip to a batch file using uber-apk-signer,
and got

provided apk path or file 'D:\sample.zip' does not exist
java.lang.IllegalArgumentException: provided apk path or file 'D:\sample.zip' does not exist
        at at.favre.tools.apksigner.ui.FileArgParser.parseAndSortUniqueFilesNonRecursive(FileArgParser.java:38)
        at at.favre.tools.apksigner.SignTool.execute(SignTool.java:60)
        at at.favre.tools.apksigner.SignTool.mainExecute(SignTool.java:45)
        at at.favre.tools.apksigner.SignTool.main(SignTool.java:33)

Cmd history for debugging purpose:
-----------------------

(exit code 1).

tries multiple variations of the arguments (including normalizing paths from backslash to forward slash),
until I've changed the extension to APK.

obviously it makes sense that u.a.s. only handles apk files (it's in the name..).

it seems like an exception that wasn't caught and thrown up until it got the the file-path exception handling method.

I personally transitioned from jarsigner, to apksigner (both can handle ZIP-DEFLATE),
to u.a.s., and a nice message (or even a meaningful exit code) would help a lot.

Error when signing

I got this error when signing APK:

Unable to determine APK's minimum supported Android platform version: malformed binary resource: AndroidManifest.xml

How to sign with APK Signature Scheme v2 enabled?

I need to resign an apk that is built with the gamedev tool Defold as it only signs with v1 but v2 is required for Android Instant Games.

I don't see in the docs for this how to enable it or maybe I'm missing something super obvious?

Request: Ablity to change Owner/Issuer Names

Hello,

Can you please make it so we can change all fields for the Owner/Issuer?

Owner: CN=Android Debug, OU=Android, O=US, L=US, ST=US, C=US
Issuer: CN=Android Debug, OU=Android, O=US, L=US, ST=US, C=US

Thanks

Could not execute zipalign

I wan to sign my apk packages but I get the following error

$ archlinux-java status
Available Java environments:
  java-11-openjdk
  java-8-jdk (default)
  java-8-openjdk

$ java -jar uber-apk-signer-1.2.1.jar....
zipalign location: BUILT_IN 
	/tmp/uapksigner-834599882927137790/linux-zipalign-29_0_2262257386856777324.tmp
keystore:
.................

01. app-release-unsigned.apk

	SIGN
	file: /home/user/..../apk/release/app-release-unsigned.apk (0.17 MiB)
	checksum: 35412b8284d3c5374cec45cd4993c544e26ef4d7b50a9c41aa6e12024a97888 (sha256)
	- could not align 
could not execute zipalign
java.lang.IllegalStateException: could not execute zipalign
	at at.favre.tools.apksigner.SignTool.execute(SignTool.java:143)
	at at.favre.tools.apksigner.SignTool.mainExecute(SignTool.java:45)
	at at.favre.tools.apksigner.SignTool.main(SignTool.java:33)

Cmd history for debugging purpose:
-----------------------
[/tmp/uapksigner-5255291507018536870/linux-zipalign-29_0_24433956931453785855.tmp, -p, -v, 4, /home/user/..../apk/release/app-release-unsigned.apk, /home/user/...././app-release-unsigned-aligned.apk]
Verifying alignment of /home/user/...././app-release-unsigned-aligned.apk (4)...
      71 res/mipmap-xhdpi-v4/ic_launcher_round.png (BAD - 3)
    3796 assets/www/cordova-js-src/platform.js (OK - compressed)
    5599 AndroidManifest.xml (OK - compressed)
    6681 res/mipmap-mdpi-v4/ic_launcher_round.png (BAD - 1)
    8285 assets/www/cordova-js-src/android/nativeapiprovider.js (OK - compressed)
    9010 assets/www/cordova.js (OK - compressed)
   25953 res/mipmap-xhdpi-v4/ic_launcher.png (BAD - 1)
   27474 res/xml/config.xml (OK - compressed)
   28542 assets/www/js/about.c1c8b494.js (OK - compressed)
   29435 res/mipmap-xhdpi-v26/ic_launcher_background.png (BAD - 3)
   29621 res/mipmap-anydpi-v26/ic_launcher_round.xml (OK - compressed)
   29902 assets/www/css/app.d0415ad6.css (OK - compressed)
   30485 res/mipmap-xxhdpi-v4/ic_launcher_round.png (BAD - 1)
   36499 assets/www/js/chunk-vendors.7584f99d.js (OK - compressed)
   85570 assets/www/cordova-js-src/plugin/android/app.js (OK - compressed)
   87093 assets/www/js/app.b38801bb.js (OK - compressed)
   91230 res/mipmap-mdpi-v4/ic_launcher.png (BAD - 2)
   92012 assets/www/index.html (OK - compressed)
   92525 res/mipmap-hdpi-v26/ic_launcher_background.png (BAD - 1)
   92674 assets/www/css/about.9f825402.css (OK - compressed)
   92782 res/drawable/ic_launcher_foreground.xml (OK - compressed)
   93578 res/mipmap-mdpi-v26/ic_launcher_background.png (BAD - 2)
   93749 assets/www/cordova-js-src/android/promptbasednativeapi.js (OK - compressed)
   94574 res/mipmap-xxxhdpi-v26/ic_launcher_background.png (BAD - 2)
   94783 res/mipmap-xxhdpi-v26/ic_launcher_background.png (BAD - 3)
   94970 res/mipmap-hdpi-v4/ic_launcher.png (BAD - 2)
   96085 res/mipmap-xxxhdpi-v4/ic_launcher.png (BAD - 1)
   99683 res/mipmap-hdpi-v4/ic_launcher_round.png (BAD - 3)
  102160 resources.arsc (OK)
  105855 assets/www/cordova-js-src/exec.js (OK - compressed)
  109416 assets/www/favicon.ico (OK - compressed)
  111259 classes.dex (OK - compressed)
  160114 res/mipmap-xxxhdpi-v4/ic_launcher_round.png (BAD - 2)
  168729 assets/www/cordova_plugins.js (OK - compressed)
  168925 res/mipmap-anydpi-v26/ic_launcher.xml (OK - compressed)
  169212 res/mipmap-xxhdpi-v4/ic_launcher.png (OK)
  171713 res/mipmap-ldpi-v26/ic_launcher_background.png (BAD - 1)
Verification FAILED
 (1)

Cert Names Are Changed - Please Fix

Hello,

I signed the framework-res.apk on my device with uber-apk-signer-1.0.0.jar and noticed that file names were changed in the META-INF.

Can we please get this fixed? I don't want these names changed,and I don't understand why you have this happening.

Original Names
CERT.RSA
CERT.SF

Changed Names
ANDROIDD.RSA
ANDROIDD.SF

Thanks

Always return null

I´am trying to run any command and always return this:

source:
null
Run with '-debug' parameter to get additional information.

INSTALL_FAILED_UPDATE_INCOMPATIBLE

APK cannot be installed after resign.

java -jar uber-apk-signer-1.2.1.jar --allowResign -a

adb install -r
Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE]

Android 6.0.1

for first look the original APK contains CERT.SF and CERT.RSA

Good APK but can't verify signature

This is apk http://www45.zippyshare.com/v/B8jwSOrZ/file.html. I can install it fine but when run with -y verifyOnly, i get this error.

  • zipalign verified
    - signature VERIFY FAILED (Unknown Heroes_v1.0.1.apk)
    ERROR: JAR signer UNKNOWNH.RSA: Failed to verify JAR signature META-INF/UNKNOWNH.RSA against META-INF/UNKNOWNH.SF: java.security.SignatureException: Algorithm constraints check failed on disabled algorithm: MD5.

How do I skip the VERIFY process?

I'd like to skip this verification, is it possible?

image

It seems like its not possible because it is not in the help command but I'll ask anyway just in case

Zipalign problem | Linux

So basically my problem is this.

On the README.md it says that there is a built in zipalign feature, however when I use uber-apk-signer on Linux to try and sign an apk, I can't sign an APK at all because because zipalign could not execute, if I run apt install zipalign however, it works, how do I utilise the built-in zipalign feature if it's possible???

Sorry I'm still very new to this repo, I used to use an older type of signer but this one is better.

class file has wrong version 55.0, should be 53.0

Keep getting this error everytime I run ./mvnw clean install, the error arises with both Java 1.8.0_252 and Java 11.0.3 for Kali Linux , done some research and can't seem to find a solution.

[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /home/kali/uber-apk-signer/src/main/java/at/favre/tools/apksigner/ui/MultiKeystoreParser.java:[6,24] cannot access java.util.stream.Collectors
bad class file: /modules/java.base/java/util/stream/Collectors.class
class file has wrong version 55.0, should be 53.0
Please remove or make sure it appears in the correct subdirectory of the classpath.
[INFO] 1 error
[INFO] -------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  13.585 s
[INFO] Finished at: 2021-11-09T04:54:32-05:00
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project uber-apk-signer: Compilation failure
[ERROR] /home/kali/uber-apk-signer/src/main/java/at/favre/tools/apksigner/ui/MultiKeystoreParser.java:[6,24] cannot access java.util.stream.Collectors
[ERROR]   bad class file: /modules/java.base/java/util/stream/Collectors.class
[ERROR]     class file has wrong version 55.0, should be 53.0
[ERROR]     Please remove or make sure it appears in the correct subdirectory of the classpath.
[ERROR] 
[ERROR] -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

Update to apksigner 30.0.2

It seems there are some breaking changes which require tests or impl to be fixed:

testSignMultipleApksMultipleCustomCert:

	SIGN
	file: C:\Users\PatrickF\AppData\Local\Temp\junit3402138880305259016\signer-test\apks\app-first-release-unsigned.apk (0.03 MiB)
	checksum: b0c0a077b3c588178e5eb0e4cd168ba2afdfbc930d5b439c868eb1a174fd40b (sha256)
java.lang.IllegalStateException: Only accepting one signer config for V4 Signature.
	at com.android.apksig.DefaultApkSignerEngine.createV4SignerConfig(DefaultApkSignerEngine.java:370)
	at com.android.apksig.DefaultApkSignerEngine.signV4(DefaultApkSignerEngine.java:914)
	at com.android.apksig.ApkSigner.sign(ApkSigner.java:582)

testResign:

junit.framework.AssertionFailedError: 
Expected :1
Actual   :2

Zipalign problem | windows 11

SIGN
file: D:\work\android\rebuild\tsxk_shiguanghb_online_4149_220721\dist\tsxk_220721.apk (2160.73 MiB)
checksum: e67c8bad5b9263816b91ab55fcada97ab65b3203498e5782ea63a9c14f1041c3 (sha256)

  • could not align
    could not execute zipalign
    Run with '--debug' parameter to get additional information.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.