| #!/usr/bin/env python3 | |
| # Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file | |
| # for details. All rights reserved. Use of this source code is governed by a | |
| # BSD-style license that can be found in the LICENSE file. | |
| import optparse | |
| import os | |
| import subprocess | |
| import sys | |
| import utils | |
| USAGE = 'usage: %prog [options] <apk>' | |
| def parse_options(): | |
| parser = optparse.OptionParser(usage=USAGE) | |
| parser.add_option('--keystore', | |
| help='keystore file (default ~/.android/app.keystore)', | |
| default='~/.android/app.keystore') | |
| parser.add_option('--sign', | |
| help='Sign the passed in apk.', | |
| default=False, | |
| action='store_true') | |
| parser.add_option('--use_apksigner', | |
| help='Use apksigner to sign.', | |
| default=False, | |
| action='store_true') | |
| parser.add_option('--output', | |
| help='Where to put the signed apk.)', | |
| default=None) | |
| (options, args) = parser.parse_args() | |
| if len(args) != 1: | |
| parser.error('Expected <apk> argument, got: ' + ' '.join(args)) | |
| apk = args[0] | |
| return (options, apk) | |
| def sign(unsigned_apk, signed_apk, keystore, quiet=False, logging=True): | |
| utils.Print('Signing (ignore the warnings)', quiet=quiet) | |
| cmd = ['zip', '-d', unsigned_apk, 'META-INF/*'] | |
| utils.RunCmd(cmd, quiet=quiet, logging=logging, fail=False) | |
| cmd = [ | |
| 'jarsigner', | |
| '-sigalg', 'SHA1withRSA', | |
| '-digestalg', 'SHA1', | |
| '-keystore', keystore, | |
| '-storepass', 'android', | |
| '-signedjar', signed_apk, | |
| unsigned_apk, | |
| 'androiddebugkey' | |
| ] | |
| utils.RunCmd(cmd, quiet=quiet) | |
| def sign_with_apksigner( | |
| unsigned_apk, signed_apk, keystore, password='android', quiet=False, | |
| logging=True): | |
| cmd = [ | |
| os.path.join(utils.getAndroidBuildTools(), 'apksigner'), | |
| 'sign', | |
| '-v', | |
| '--ks', keystore, | |
| '--ks-pass', 'pass:' + password, | |
| '--min-sdk-version', '19', | |
| '--out', signed_apk, | |
| unsigned_apk | |
| ] | |
| utils.RunCmd(cmd, quiet=quiet, logging=logging) | |
| def main(): | |
| (options, apk) = parse_options() | |
| if options.sign: | |
| if not options.output: | |
| print('When signing you must specify an output apk') | |
| return 1 | |
| if not options.keystore: | |
| print('When signing you must specify a keystore') | |
| return 1 | |
| if options.use_apksigner: | |
| sign_with_apksigner(apk, options.output, options.keystore) | |
| else: | |
| sign(apk, options.output, options.keystore) | |
| return 0 | |
| if __name__ == '__main__': | |
| sys.exit(main()) |