Transparencia de código para paquetes de aplicaciones

La transparencia de código es un mecanismo opcional de firma y verificación de código para apps publicadas con Android App Bundle. Utiliza una clave de firma de transparencia de código, que es propiedad exclusiva del desarrollador de apps.

La transparencia de código es independiente del esquema de firma que se usa en paquetes de aplicaciones y APK. La clave de transparencia de código difiere de la clave de firma de la app almacenada en la infraestructura segura de Google cuando se usa la firma de apps de Play.

Cómo funciona la transparencia de código

El proceso consiste en la inclusión de un archivo de transparencia de código en el paquete después de su compilación, pero antes de subirlo a Play Console para su distribución.

Dicho archivo es un token web JSON (JWT) que contiene una lista de archivos DEX y bibliotecas nativas incluidas en el paquete, así como sus hash. Luego, se firma con la clave de transparencia de código que solo el desarrollador posee.

Diagrama de transparencia de código

Este archivo de transparencia de código se propaga al APK base que se compiló a partir del paquete de aplicación (específicamente, a la división principal del módulo base). Luego, podrá verificarse lo siguiente:

  • Todos los archivos DEX y de código nativo presentes en los APK tienen hashes coincidentes en el archivo de transparencia de código.
  • El componente de clave pública correspondiente a la clave de firma de transparencia de código de la app coincide con la clave pública del desarrollador (que este debe proporcionar por medio de un canal seguro e independiente).

En conjunto, esta información verifica que el código contenido en los APK no se modificó y que coincide con lo previsto por el desarrollador.

El archivo de transparencia de código no verifica recursos, elementos, el manifiesto de Android ni ningún otro archivo distinto a los de tipo DEX o a bibliotecas nativas contenidas en la carpeta lib/.

La verificación de transparencia de código se usa con el único propósito de que tanto desarrolladores como usuarios finales puedan inspeccionar el código y asegurarse de que el que están ejecutando coincide con el que el desarrollador de apps compiló y firmó originalmente.

Limitaciones conocidas

Hay ciertas situaciones en las que no se puede usar la transparencia de código:

  • Las apps que especifican el atributo sharedUserId en el manifiesto, ya que podrían compartir su proceso con otras y eso dificulta comprobar la fiabilidad del código en ejecución
  • Las apps que usan protección contra manipulaciones o cualquier otro servicio que realice cambios de código después de que se genere el archivo de transparencia del código harán que la verificación de transparencia de código falle
  • Las apps que usan multidex heredado en niveles de API inferiores a 21 (Android 5.0) y que usan módulos de funciones (la transparencia de código seguirá funcionando cuando la app se instale desde Google Play en dispositivos con Android 5.0 o versiones posteriores, pero se inhabilitará en versiones anteriores del SO)

Cómo agregar transparencia de código

Antes de agregar transparencia de código a tu app, asegúrate de tener un par de claves pública y privada que puedas usar para la firma de transparencia de código. Debe ser una clave única y diferente de la clave de firma que usas para la firma de apps de Play, debe conservarse de manera segura y no debe compartirse fuera de tu organización.

Si no tienes una clave, puedes seguir las instrucciones de la guía Cómo firmar tu app a fin de generar una en tu máquina. La transparencia de código usa un archivo estándar de almacén de claves, por lo que, aunque la guía trata sobre la firma de apps, el proceso de generación de claves es el mismo.

Cómo usar el complemento de Android para Gradle

La compatibilidad con la transparencia de código requiere la versión 7.1.0-alpha03 o posterior del complemento de Android para Gradle. A fin de configurar la clave que se usa para la firma de transparencia de código, agrega lo siguiente en el bloque bundle.

Groovy

// In your app module's build.gradle file:
android {
    ...
    bundle {
        codeTransparency {
            signing {
                keyAlias = "ALIAS"
                keyPassword = "PASSWORD"
                storeFile = file("path/to/keystore")
                storePassword = "PASSWORD"
            }
        }
        ...
    }
}

Kotlin

// In your app module's build.gradle.kts file:
android {
    ...
    bundle {
        codeTransparency {
            signing {
                keyAlias = "ALIAS"
                keyPassword = "PASSWORD"
                storeFile = file("path/to/keystore")
                storePassword = "PASSWORD"
            }
        }
        ...
    }
}

La clave que se use deberá ser una que utilices solo para fines de transparencia de código, no la clave que usa la firma de apps de Play.

Cómo usar bundletool en la línea de comandos

La compatibilidad con la transparencia de código requiere Bundletool versión 1.7.0 o posterior, que puedes descargar desde GitHub.

Ejecuta el siguiente comando para agregar transparencia de código a un Android App Bundle. La clave que se use deberá ser una que utilices solo para fines de transparencia de código, no la clave que usa la firma de apps de Play.

bundletool add-transparency \
  --bundle=/MyApp/my_app.aab \
  --output=/MyApp/my_app_with_transparency.aab \
  --ks=/MyApp/keystore.jks \
  --ks-pass=file:/MyApp/keystore.pwd \
  --ks-key-alias=MyKeyAlias \
  --key-pass=file:/MyApp/key.pwd

Como alternativa, si quieres usar tus propias herramientas de firma, puedes usar Bundletool con el propósito de generar el archivo de transparencia de código sin firmar, firmarlo en un entorno separado e insertar la firma en el paquete:

# Generate code transparency file
bundletool add-transparency \
  --mode=generate_code_transparency_file \
  --bundle=/MyApp/my_app.aab \
  --output=/MyApp/code_transparency_file.jwt \
  --transparency-key-certificate=/MyApp/transparency.cert

# Add code transparency signature to the bundle
bundletool add-transparency \
  --mode=inject_signature \
  --bundle=/MyApp/my_app.aab \
  --output=/MyApp/my_app_with_transparency.aab \
  --transparency-key-certificate=/MyApp/transparency.cert \
  --transparency-signature=/MyApp/signature

Cómo verificar la transparencia de código de una app

Existen diferentes métodos para verificar el código en virtud del archivo de transparencia de código, en función de si los APK se instalaron en un dispositivo Android o si se descargaron de forma local en tu computadora.

Cómo usar Bundletool para verificar un paquete de aplicación o un conjunto de APK

Puedes usar Bundletool con el fin de verificar la transparencia de código en un paquete de aplicación o un conjunto de APK. Usa el comando check-transparency a los efectos de imprimir la huella digital del certificado público:

# For checking a bundle:
bundletool check-transparency \
  --mode=bundle \
  --bundle=/MyApp/my_app_with_transparency.aab

No APK present. APK signature was not checked.
Code transparency signature is valid. SHA-256 fingerprint of the code transparency key certificate (must be compared with the developer's public key manually): 01 23 45 67 89 AB CD EF ..
Code transparency verified: code related file contents match the code transparency file.


# For checking a ZIP containing app's APK splits:
bundletool check-transparency \
  --mode=apk \
  --apk-zip=/MyApp/my_app_with_transparency.zip

APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): 02 34 E5 98 CD A7 B2 12 ..
Code transparency signature is valid. SHA-256 fingerprint of the code transparency key certificate (must be compared with the developer's public key manually): 01 23 45 67 89 AB CD EF ..
Code transparency verified: code related file contents match the code transparency file.

De manera opcional, puedes especificar el certificado público con el que deseas verificar el paquete o conjunto de APK de modo que no necesites comparar los hash manualmente:

bundletool check-transparency \
  --mode=bundle \
  --bundle=/MyApp/my_app_with_transparency.aab \
  --transparency-key-certificate=/MyApp/transparency.cert

No APK present. APK signature was not checked.
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.


bundletool check-transparency \
  --mode=apk \
  --apk-zip=/MyApp/my_app_with_transparency.zip \
  --apk-signing-key-certificate=/MyApp/apk.cert \
  --transparency-key-certificate=/MyApp/transparency.cert

APK signature verified for the provided apk signing key certificate.
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.

Cómo usar Bundletool para verificar una app instalada en un dispositivo

Si deseas verificar una app instalada en un dispositivo Android, asegúrate de que este se encuentre conectado a tu computadora a través de ADB y ejecuta el siguiente comando:

bundletool check-transparency \
  --mode=connected_device \
  --package-name="com.my.app"

APK signature is valid. SHA-256 fingerprint of the apk signing key certificate (must be compared with the developer's public key manually): 02 34 E5 98 CD A7 B2 12 ..
Code transparency signature is valid. SHA-256 fingerprint of the code transparency key certificate (must be compared with the developer's public key manually): 01 23 45 67 89 AB CD EF ..
Code transparency verified: code related file contents match the code transparency file.

De manera opcional, la verificación de transparencia del dispositivo conectado también puede comprobar la firma en virtud de una clave pública que especifiques:

bundletool check-transparency \
  --mode=connected-device \
  --package-name="com.my.app" \
  --apk-signing-key-certificate=/MyApp/apk.cert \
  --transparency-key-certificate=/MyApp/transparency.cert

APK signature verified for the provided apk signing key certificate.
Code transparency signature verified for the provided code transparency key certificate.
Code transparency verified: code related file contents match the code transparency file.