Transparência do código para pacotes de app

A transparência do código é um mecanismo opcional de verificação e assinatura de código para apps publicados com o Android App Bundle. Ela usa uma chave de assinatura, que é exclusiva do desenvolvedor de apps.

A transparência do código é independente do esquema de assinatura usado para pacotes de apps e APKs. A chave de transparência do código é diferente da chave de assinatura do app armazenada na infraestrutura segura do Google ao usar a Assinatura de apps do Google Play.

Como funciona a transparência do código

O processo inclui um arquivo de transparência de código no pacote após a criação, mas antes do envio ao Play Console para distribuição.

O arquivo de transparência do código é um JSON Web Token (JWT) que contém uma lista de arquivos DEX e bibliotecas nativas incluídas no pacote, além dos respectivos hashes. Em seguida, ele é assinado usando a chave de transparência do código que é armazenada apenas pelo desenvolvedor.

Diagrama da transparência do código

Esse arquivo de transparência de código é propagado para o APK básico criado do pacote de apps (especificamente para a divisão principal do módulo base). Em seguida, é possível verificar se:

  • todos os arquivos DEX e de código nativo presentes nos APKs têm hashes correspondentes no arquivo de transparência do código;
  • o componente de chave pública da chave de assinatura de transparência do código no app é igual à chave pública do desenvolvedor, que precisa ser fornecida pelo desenvolvedor por um canal separado e seguro.

Juntas, essas informações verificam se o código contido nos APKs é igual ao que o desenvolvedor pretendia fornecer e se ele não foi modificado.

O arquivo de transparência do código não verifica recursos, o manifesto do Android ou qualquer outro arquivo que não sejam os arquivos DEX ou bibliotecas nativas contidos na pasta lib/.

A verificação de transparência de código é usada exclusivamente para fins de inspeção por desenvolvedores e usuários finais, que querem garantir que o código em execução corresponde ao código criado e assinado originalmente pelo desenvolvedor de apps.

Limitações conhecidas

Há determinadas situações em que a transparência do código não pode ser usada:

  • Apps que especificam o atributo sharedUserId no manifesto. Esses aplicativos podem compartilhar o processo com outros apps, o que dificulta verificar o código em execução.
  • Os apps que usam o recurso de proteção contra adulterações ou qualquer outro serviço que faça alterações de código após a geração do arquivo de transparência de código farão com que a verificação de transparência falhe.
  • Apps que usam o multidex legado em níveis de API anteriores ao 21 (Android 5.0) e usam módulos de recursos. A transparência do código continuará funcionando quando o app for instalado pelo Google Play em dispositivos Android 5.0 ou mais recentes. A transparência do código será desativada em versões mais antigas do SO.

Como adicionar a transparência de código

Antes de adicionar transparência de código ao app, verifique se você tem um par de chaves privada e pública que possa ser usado para a assinatura de transparência de código. Essa chave precisa ser exclusiva e diferente da usada na assinatura de apps do Google Play e precisa ser mantida com segurança e nunca compartilhada fora da organização.

Se você não tiver uma chave, siga as instruções no guia Assinar seu app para gerar uma na sua máquina. A transparência de código usa um arquivo de keystore padrão. Assim, mesmo que o guia seja para assinatura de apps, o processo de geração de chaves será o mesmo.

Como usar o Plug-in do Android para Gradle

A compatibilidade com a transparência de código exige o Plug-in do Android para Gradle versão 7.1.0-alpha03 ou mais recente. Para configurar a chave usada na assinatura da transparência do código, adicione o código a seguir ao bloco 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"
            }
        }
        ...
    }
}

A chave usada precisa ser a utilizada apenas para a transparência do código, e não a chave de assinatura do app usada pela Assinatura de apps do Google Play.

Como usar bundletool na linha de comando

A compatibilidade com a transparência de código requer o bundletool versão 1.7.0 ou mais recente, do qual você pode fazer o download no GitHub (link em inglês).

Execute o comando a seguir para adicionar transparência de código a um Android App Bundle. A chave usada precisa ser a utilizada apenas para a transparência do código, e não a chave de assinatura do app usada pela Assinatura de apps do Google 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, se você quiser usar suas próprias ferramentas de assinatura, poderá usar o bundletool para gerar o arquivo de transparência do código não assinado, assiná-lo em um ambiente separado e injetar a assinatura no pacote:

# 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

Verificar a transparência do código de um app

Existem métodos diferentes para verificar o código no arquivo de transparência dele, dependendo se os APKs estão instalados em um dispositivo Android ou se foram transferidos por download localmente para seu computador.

Como usar o Bundletool para verificar um pacote de app ou um conjunto de APKs

Você pode usar o bundletool para verificar a transparência do código em um pacote de app ou em um conjunto de APKs. Use o comando check-transparency para exibir a impressão digital do 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.

Como opção, é possível especificar o certificado público que você quer usar para verificar o pacote ou conjunto de APKs, para que não seja preciso comparar os hashes 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.

Como usar o Bundletool para verificar um app instalado em um dispositivo

Para verificar um app que foi instalado em um dispositivo Android, verifique se ele está conectado ao computador pelo ADB e use o comando a seguir:

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.

A verificação de transparência do dispositivo conectado também pode, opcionalmente, verificar a assinatura em relação a uma chave pública especificada:

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.