apksigner

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 atributo minSdkVersion 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 comando apksigner 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 o utf-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 comando apksigner 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 constante keystore.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 atributo minSdkVersion 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