La herramienta apksigner
(disponible a partir de la revisión 24.0.3 de las Herramientas de compilación del SDK de Android) te permite firmar APK y confirmar que la firma del APK se verificará correctamente en todas las versiones de la plataforma Android compatibles con el APK. En esta página, se presenta una breve guía sobre cómo usar la herramienta y sirve como referencia para las diferentes opciones de línea de comandos que admite la herramienta. Si quieres obtener una descripción más completa de cómo se usa la herramienta apksigner
para firmar tus APK, consulta la guía sobre Cómo firmar tu app.
Precaución: Si firmas tu APK con un apksigner
y haces cambios adicionales en el APK, se invalidará la firma.
Por lo tanto, debes usar herramientas como zipalign
antes de firmar tu APK.
Uso
Firmar un APK
La sintaxis para firmar un APK con la herramienta apksigner
es la siguiente:
apksigner sign --ks keystore.jks | --key key.pk8 --cert cert.x509.pem [signer_options] app-name.apk
Cuando firmes un APK con la herramienta apksigner
, deberás proporcionar la clave privada y el certificado del firmante. Puedes incluir esta información de dos maneras diferentes:
-
Especifica un archivo de almacén de claves mediante la opción
--ks
. -
Especifica el archivo de clave privada y el archivo de certificado por separado, por medio de las opciones
--key
y--cert
, respectivamente. El archivo de clave privada debe usar el formato PKCS #8 y el de certificado, el formato X.509.
Por lo general, firmas un APK con un solo firmante. En el caso de que necesites firmar un APK con varios firmantes, usa la opción --next-signer
para separar el conjunto de opciones generales que se aplicarán a cada firmante:
apksigner sign [signer_1_options] --next-signer [signer_2_options] app-name.apk
Cómo verificar la firma de un APK
La sintaxis que se usa para confirmar que la firma del APK se verificará correctamente en las plataformas compatibles es la siguiente:
apksigner verify [options] app-name.apk
Cómo girar claves de firma
La sintaxis para rotar un lineage de certificado de firma (o una nueva secuencia de firmas) es la siguiente:
$ apksigner rotate --in /path/to/existing/lineage \ --out /path/to/new/file \ --old-signer --ks old-signer-jks \ --new-signer --ks new-signer-jks
Opciones
En las siguientes listas, se incluye el conjunto de opciones para cada comando que admite la herramienta apksigner
.
Comando de firma
Opciones generales
Las siguientes opciones especifican configuraciones básicas que pueden aplicarse a un firmante:
--out <apk-filename>
- Corresponde a la ubicación donde quieras guardar el APK firmado. Si esta opción no se proporciona explícitamente, el paquete de APK se firma en el lugar y sobrescribe el archivo APK de entrada.
--min-sdk-version <integer>
-
Corresponde al nivel de API de marco de trabajo de Android más bajo que usa
apksigner
para confirmar que se verificará la firma del APK. Los valores más altos permiten que la herramienta use parámetros de seguridad más fuertes cuando firma la app, pero limitan la disponibilidad del APK a dispositivos que ejecutan versiones más recientes de Android. De forma predeterminada,apksigner
usa el valor del atributominSdkVersion
del archivo de manifiesto de la app. --max-sdk-version <integer>
-
Corresponde al nivel de API de marco de trabajo de Android más alto que usa
apksigner
para confirmar que se verificará la firma del APK. De manera predeterminada, la herramienta usa el nivel de API más alto posible. --v1-signing-enabled <true | false>
-
Determina si
apksigner
firma el paquete de APK mediante el esquema de firma tradicional basado en JAR. De manera predeterminada, la herramienta usa los valores de--min-sdk-version
y--max-sdk-version
para decidir cuándo aplicar este esquema de firma. --v2-signing-enabled <true | false>
-
Determina si
apksigner
firma el paquete de APK mediante el Esquema de firma de APK v2. De manera predeterminada, la herramienta usa los valores de--min-sdk-version
y--max-sdk-version
para decidir cuándo aplicar este esquema de firma. -v
,--verbose
- Usa el modo de salida detallado.
Opciones por firmante
Las siguientes opciones especifican la configuración de un firmante en particular. Estas no son necesarias si firmas tu app con un solo firmante.
--next-signer <signer-options>
- Se usa a fin de especificar diferentes opciones generales para cada firmante.
--v1-signer-name <basename>
-
Corresponde al nombre base de los archivos que componen la firma basada en JAR para el firmante actual. De manera predeterminada,
apksigner
usa el alias de clave del almacén de claves o el nombre base del archivo de clave para este firmante.
Opciones de clave y certificado
Las siguientes opciones especifican la clave privada y el certificado del firmante:
--ks <filename>
-
La clave privada y la cadena de certificados del firmante residen en el archivo de almacén de claves específico basado en Java. Si el nombre de archivo se configura en
"NONE"
, el almacén de claves que contiene la clave y el certificado no necesita un archivo especificado, como es el caso de algunos almacenes de claves PKCS #11. --ks-key-alias <alias>
- Corresponde al nombre del alias que representa la clave privada del firmante y los datos del certificado dentro del almacén de claves. Si el almacén de claves asociado con el firmante contiene varias claves, debes especificar esta opción.
--ks-pass <input-format>
-
Corresponde a la contraseña para el almacén de claves que contiene la clave privada y el certificado del firmante. Debes proporcionar una contraseña para abrir un almacén de claves. La herramienta
apksigner
admite los siguientes formatos:-
pass:<password>
: La contraseña se proporciona intercalada con el resto del comandoapksigner sign
. -
env:<name>
: La contraseña se almacena en la variable de entorno determinada. -
file:<filename>
: La contraseña se almacena como una sola línea en el archivo determinado. -
stdin
: La contraseña se proporciona como una sola línea en el flujo de entrada estándar. Este es el comportamiento predeterminado de--ks-pass
.
Nota: Si incluyes varias contraseñas en el mismo archivo, especifícalas en líneas separadas. La herramienta
apksigner
asocia las contraseñas con los firmantes de un APK en función del orden en que especifiques los firmantes. Si proporcionaste dos contraseñas para un firmante,apksigner
interpretará que la primera es la contraseña del almacén de claves y la segunda, la de la clave. -
--pass-encoding <charset>
-
Incluye las codificaciones de caracteres especificadas (como
ibm437
outf-8
) cuando se intentan administrar contraseñas que contienen caracteres que no son ASCII.Keytool a menudo convierte la contraseña con el charset predeterminado de la consola a fin de encriptar los almacenes de claves. De manera predeterminada,
apksigner
intenta desencriptarlos mediante varios formularios de la contraseña: el formulario Unicode, el formulario codificado con el charset predeterminado de JVM y, en Java 8 y versiones anteriores, el formulario codificado con el charset predeterminado de la consola. En Java 9,apksigner
no puede detectar el charset de la consola. Por lo tanto, es posible que debas especificar--pass-encoding
cuando se use una contraseña que no sea ASCII. Además, puede que debas especificar esta opción con los almacenes de claves que creó Keytool en un sistema operativo diferente o en un entorno local diferente. --key-pass <input-format>
-
Corresponde a la contraseña para la clave privada del firmante, que es necesaria si la clave privada está protegida por contraseña. La herramienta
apksigner
admite los siguientes formatos:-
pass:<password>
: La contraseña se proporciona intercalada con el resto del comandoapksigner sign
. -
env:<name>
: La contraseña se almacena en la variable de entorno determinada. -
file:<filename>
: La contraseña se almacena como una sola línea en el archivo determinado. -
stdin
: La contraseña se proporciona como una sola línea en el flujo de entrada estándar. Este es el comportamiento predeterminado de--key-pass
.
Nota: Si incluyes varias contraseñas en el mismo archivo, especifícalas en líneas separadas. La herramienta
apksigner
asocia las contraseñas con los firmantes de un APK en función del orden en que especifiques los firmantes. Si proporcionaste dos contraseñas para un firmante,apksigner
interpretará que la primera es la contraseña del almacén de claves y la segunda, la de la clave. -
--ks-type <algorithm>
-
Corresponde al tipo o algoritmo asociado con el almacén de claves que contiene la clave privada y el certificado del firmante. De manera predeterminada,
apksigner
usa el tipo definido como la constantekeystore.type
en el archivo de propiedades de Seguridad. --ks-provider-name <name>
-
Corresponde al nombre del proveedor de JCA que se usará al solicitar la implementación del almacén de claves del firmante. De manera predeterminada,
apksigner
usa el proveedor de mayor prioridad. --ks-provider-class <class-name>
-
Corresponde al nombre de clase completamente calificado del proveedor de JCA que se usará al solicitar la implementación del almacén de claves del firmante. Esta opción sirve como alternativa para
--ks-provider-name
. De manera predeterminada,apksigner
usa el proveedor especificado con la opción--ks-provider-name
. --ks-provider-arg <value>
-
Corresponde a un valor de string para pasar como argumento al constructor de la clase de proveedor de JCA; la clase en sí se define con la opción
--ks-provider-class
. De manera predeterminada,apksigner
usa el constructor de 0 argumentos de la clase. --key <filename>
-
Corresponde al nombre del archivo que contiene la clave privada del firmante. Este archivo debe usar el formato DER PKCS #8. Si la clave está protegida por contraseña, un
apksigner
solicita la contraseña mediante la entrada estándar a menos que especifiques un tipo diferente de formato de entrada por medio de la opción--key-pass
. --cert <filename>
- Corresponde al nombre del archivo que contiene la cadena de certificados del firmante. Este archivo debe usar el formato DER o PEM X.509.
Comando de verificación
--print-certs
- Muestra información sobre los certificados de firma del APK.
--min-sdk-version <integer>
-
Corresponde al nivel de API de marco de trabajo de Android más bajo que usa
apksigner
para confirmar que se verificará la firma del APK. Los valores más altos permiten que la herramienta use parámetros de seguridad más fuertes cuando firma la app, pero limitan la disponibilidad del APK a dispositivos que ejecutan versiones más recientes de Android. De forma predeterminada,apksigner
usa el valor del atributominSdkVersion
del archivo de manifiesto de la app. --max-sdk-version <integer>
-
Corresponde al nivel de API de marco de trabajo de Android más alto que usa
apksigner
para confirmar que se verificará la firma del APK. De manera predeterminada, la herramienta usa el nivel de API más alto posible. -v
,--verbose
- Usa el modo de salida detallado.
-Werr
- Trata las alertas como errores.
Ejemplos
Firmar un APK
Firma un APK con release.jks
, que es la única clave en el almacén de claves:
$ apksigner sign --ks release.jks app.apk
Firma un APK con una clave privada y un certificado, que se almacenan como archivos separados:
$ apksigner sign --key release.pk8 --cert release.x509.pem app.apk
Firma un APK con dos claves:
$ apksigner sign --ks first-release-key.jks --next-signer --ks second-release-key.jks app.apk
Cómo verificar la firma de un APK
Comprueba si se espera que las firmas del APK se confirmen como válidas en todas las plataformas de Android que admite el APK:
$ apksigner verify app.apk
Comprueba si se espera que las firmas del APK se confirmen como válidas en Android 4.0.3 (nivel de API 15) y versiones posteriores:
$ apksigner verify --min-sdk-version 15 app.apk
Cómo girar claves de firma
Habilita un lineage de certificado de firma que admita la rotación de claves:
$ apksigner rotate --out /path/to/new/file --old-signer \ --ks release.jks --new-signer --ks release2.jks
Vuelve a girar tus claves de firma:
$ apksigner rotate --in /path/to/existing/lineage \ --out /path/to/new/file --old-signer --ks release2.jks \ --new-signer --ks release3.jks