
[TÉCNICO] Firma con apksigner y el esquema de firma APK Signature Scheme v2
En la publicación anterior (ANDROID APP SIGNING & ZIPALIGN), discutimos cómo firmar archivos APK y AAB utilizando jarsigner con el esquema de firma APK Signature Scheme v1.
En esta publicación, hablaremos sobre la firma de archivos APK utilizando apksigner.
Es posible que te preguntes por qué es necesario conocer apksigner si podemos utilizar jarsigner.
El esquema de firma APK Signature Scheme v2 se introdujo en Android 7.0 para proporcionar una protección más sólida a los archivos APK.
Posteriormente, se introdujeron APK Signature Scheme v3 en Android 9.0 y APK Signature Scheme v4 en Android 11.0.

Antes del esquema de firma APK Signature Scheme v2, la firma de los archivos APK se realizaba mediante jarsigner basado en Signed JAR.
Desde la versión v2, la firma comenzó a basarse en apksigner.
¿Cuándo se debe firmar con apksigner?
- Si la opción Signature Versions v2 se seleccionó al compilar la aplicación (APK Signature Scheme v2).
- Si el targetSdkVersion es superior a 30 al compilar la aplicación.
En estos casos, la firma debe realizarse obligatoriamente con apksigner.
Si bien la firma con jarsigner no genera problemas al instalar y ejecutar la aplicación, podría generar errores al subir la app a Google Play Console.
Cómo verificar la versión del esquema de firma en una app
Si en la opción "Generate Signed Bundle or APK" está seleccionada "V2 (Full APK Signature)"

java -jar [apksigner.jar Path] verify -v --print-certs [Apk’s Path before applying LIAPP]
Si la salida muestra: "Verified using v2 scheme (APK Signature Scheme v2): true", entonces la aplicación está firmada con APK Signature Scheme v2.
zipalign
Un punto importante: si utilizas apksigner, zipalign debe ejecutarse antes de la firma del APK.
Si realizas cambios en el APK después de firmarlo con apksigner, la firma se invalidará.
Por lo tanto, zipalign debe ejecutarse antes de la firma.
zipalign -f -v 4 "apk file Path that needs zipalign" "apk file Path that will be saved after zipalign-ing "

Firma con apksigner
[ Windows ]
java -jar [APKSIGNER_PATH] sign -v --out [SAVED_APK_PATH] --ks [KEYSTORE_PATH] --ks-key-alias [ALIAS_NAME] [APK_FILE_PATH]
[ MAC ]
[APKSIGNER_PATH] sign -v --out [SAVED_APK_PATH] --ks [KEYSTORE_PATH] --ks-key-alias [ALIAS_NAME] [APK_FILE_PATH]
Puedes encontrar apksigner en la siguiente ubicación dentro del SDK de Android:
1) Check SDK path in the Android Studio
Tool menu => SDK Manager => Android SDK Location path check
2) Check Apksigner file from the SDK directory
SDK Directory => build-tools directory =>buildToolsVersion directory =>lib directory =>check apksigner.jar file
En Mac, el archivo apksigner se encuentra en la carpeta de build-tools correspondiente a la versión de compilación.
Keystore password for signer #1:
Los caracteres de la contraseña no se mostrarán en pantalla, pero se están ingresando.
Si la contraseña del keystore y la clave del alias son las mismas, la firma procederá automáticamente.
Si son diferentes, se te pedirá la contraseña de la clave privada (key password):
Key "KEY_NAME" password for signer #1:
Si introduces la contraseña correcta, la firma se completará y verás el mensaje: Signed.

[ Windows ]
java -jar [APKSIGNER_PATH] sign -v --out [SAVED_APK_PATH] --ks [KEYSTORE_PATH] --ks-pass pass:"keystore_password" --key-pass pass:"key_password" --ks-key-alias [ALIAS_NAME] [APP_FILE_PATH]
[ MAC ]
[APKSIGNER_PATH] sign -v --out [SAVED_APK_PATH] --ks [KEYSTORE_PATH] --ks-pass pass:"keystore_password" --key-pass pass:"key_password" --ks-key-alias [ALIAS_NAME] [APP_FILE_PATH]
Verificar firma con apksigner
[ Windows ]
java -jar [APKSIGNER_PATH] verify -v --print-certs [APP_FILE_PATH]
[ MAC ]
[APKSIGNER_PATH] verify -v --print-certs [APP_FILE_PATH]
Si la firma se realizó correctamente, verás lo siguiente: Verified using v2 scheme (APK Signature Scheme v2): true

zipalign & Signing with script file
[ Bat file for Window users]
[ Sh file for MAC users]
Abre el script con un editor de texto y edita los siguientes valores:
KeyStorePath="Keystore Path"
ALIAS_NAME="Alias Name"
STORE_PASS="Keystore Password"
KEY_PASS="Key Password"
ZIP_ALIGN="zipalign file path"
APKSIGNER_PATH="apksigner file path"
Los archivos zipalign y apksigner se encuentran en la carpeta build-tools dentro de la ruta donde está instalado el Android SDK.
Si deseas ingresar tu propia contraseña sin guardarla, debes eliminar las opciones relacionadas con --ks-pass y --key-pass.
Los usuarios de Windows pueden arrastrar el archivo de la aplicación que se va a firmar al archivo LIAPP_sign_window.bat, y se ejecutará de inmediato.
Los usuarios de Mac pueden ejecutar un programa de terminal arrastrando los archivos de script y la aplicación en orden, o ingresando las rutas como se muestra a continuación.
Ex. /Users/username/Downloads/LIAPP_apksign_mac.sh /Users/username/AndroidStudioProjects/MyApplication/app/release/app-release.apk
Ex. chmod +x /Users/username/Downloads/LIAPP_apksign_mac.sh
Una vez que se ejecute correctamente, primero se aplicará zipalign y luego se realizará la firma.
Si durante el proceso de firma no se presentan problemas y aparece el mensaje "Signed.", presiona cualquier tecla para continuar con la firma.
El archivo firmado se guardará con "_signed" añadido al nombre del archivo.
Para más información sobre la firma con apksigner y el esquema APK Signature Scheme, consulta el siguiente enlace:
apksigner : https://developer.android.com/studio/command-line/apksigner
app-signing : https://developer.android.com/studio/publish/app-signing
APK Signature Scheme : https://source.android.com/security/apksigning
LIAPP, brindamos el mejor servicio posible.