Esquema de assinatura de APK v3.1

Visão geral

O Android 13 oferece suporte ao esquema de assinatura de APK v3.1, uma melhoria em relação ao esquema de assinatura de APK v3. O esquema v3.1 trata de alguns dos problemas conhecidos do esquema de assinatura de APK v3 com relação à rotação. Mais especificamente, o esquema de assinatura v3.1 oferece suporte ao direcionamento de versão do SDK, o que permite que a rotação seja destinada a uma versão mais recente da plataforma.

O esquema de assinatura v3.1 usa um ID de bloco que não é reconhecido no Android 12 ou versões anteriores. Portanto, a plataforma aplica este comportamento de signatário:

  • Dispositivos com o Android 13 ou versões mais recentes usam o signatário alternado no bloco v3.1.
  • Dispositivos com versões mais antigas do Android ignoram o signatário alternado e usam o signatário original no bloco v3.

Em apps que ainda não alternaram a chave de assinatura, nenhuma outra ação é necessária. Quando esses apps optarem por alternar, o sistema vai aplicar o novo esquema de assinatura v3.1 por padrão.

Bloco de assinatura v3.1

O bloco de assinatura v3.1 terá o mesmo conteúdo do bloco de assinatura v3, mas com o novo ID de bloco. Essas assinaturas só serão reconhecidas em dispositivos com o Android 13 e versões mais recentes. Isso permite que os apps alternem as chaves de assinatura com segurança sem precisar se preocupar com APKs de vários destinos, já que o signatário original pode ser usado para assinar o APK no bloco de assinatura v3 e o signatário alternado no bloco de assinatura v3.1. Isso também permite que a plataforma reutilize todos os códigos de verificação existentes para o bloco de assinatura v3 ao verificar uma assinatura v3.1.

Por padrão, a biblioteca apksig vai usar o bloco de assinatura v3.1 sempre que uma chave e uma linhagem alternadas forem fornecidas na configuração de assinatura. Se o minSdkVersion de um app for inferior ao Android 13 e uma chave alternada estiver sendo usada, a chave de assinatura original também precisa ser especificada para que possa ser usada para assinar o APK no bloco de assinatura v3. Isso é semelhante ao comportamento atual em que o signatário original é necessário se o APK for direcionado a uma versão anterior ao Android 9.

Para oferecer suporte à rotação de chaves de segmentação a partir de uma versão específica do SDK, a biblioteca apksig vai expor novas APIs que permitem definir uma versão mínima do SDK para rotação. Se uma versão do SDK anterior ao Android 13 for especificada como a versão mínima para suporte à rotação, o bloco v3 original será usado. O bloco de assinatura v3.1 só é usado na presença de rotação, em que a versão mínima do SDK para rotação é definida como Android 13 e versões mais recentes. O bloco de assinatura v3 terá um novo atributo para a proteção mínima de remoção de versão do SDK.

O APK inclui a linhagem Valor de rotation-min-sdk-version Bloco de assinatura v3 Bloco de assinatura v3.1
Não Padrão ou qualquer valor (representado por x abaixo) Assinado com o signatário original, destinado ao Android 9 e versões mais recentes Não há
Sim Padrão Assinado com o signatário original, destinado ao Android 9 até o 12L Assinado com um assinador alternado, destinado ao Android 13 e versões mais recentes
Sim x < 33 (Android 13) Assinado com um signatário alternado, destinado ao Android 9 e versões mais recentes Não há
Sim x >= 33 (Android 13) Assinado com o signatário original, com direcionamento para o Android 9 - (x-1) Assinado com um signatário alternado, segmentado para x+

Problemas relacionados à rotação

Os seguintes problemas relacionados à rotação foram resolvidos na plataforma:

Correções do Android 12

  • A plataforma só concederia uma permissão de assinatura a um app solicitante se o signatário atual de um dos apps estiver na linhagem de assinatura ou for o signatário atual do outro app. Isso impede a concessão de uma permissão de assinatura a um app solicitante se os dois apps seguirem as práticas recomendadas de chaves de assinatura e rotacionarem para chaves de assinatura diferentes.
  • O recurso de reversão de APK da plataforma não conseguia reverter um APK que tinha acabado de ter a chave de assinatura alterada, a menos que a chave anterior na linhagem de assinatura tivesse o recurso de reversão. No entanto, esse recurso contraria o propósito da rotação, já que permite que uma nova atualização de pacote seja assinada pela chave de assinatura anterior e reverta a chave alterada.
  • Um APK assinado apenas com a chave alternada e atualizado posteriormente com um APK assinado com a chave original e a chave alternada na linhagem só vai mostrar a chave alternada na linhagem em dispositivos com o Android 11 e versões anteriores.

Correções do Android 11

  • O PackageManager#checkSignatures não foi atualizado corretamente para verificar as chaves de assinatura originais de dois pacotes. Isso quebrou a instrumentação para apps que usavam uma chave de assinatura alternada com o APK de instrumentação usando a chave de assinatura original.
  • Os pacotes em um sharedUserId compartilham a linhagem de assinatura. Sempre que um app com uma linhagem de assinatura atualizada é instalado ou atualizado em um sharedUiserId, a linhagem desse app substitui a linhagem compartilhada do sharedUserId. Ou seja, se a linhagem de assinatura de um app for A -> B e um app for atualizado no sharedUserId com a linhagem B -> C, a linhagem do sharedUserId será substituída por B -> C. Da mesma forma, os recursos de um signatário anterior na linhagem não podiam ser atualizados, a menos que a linhagem de assinatura fosse alterada.

Integração com a v4

O esquema de assinatura v4 usa a configuração de assinatura fornecida ao apksigner. No caso de várias configurações de assinatura fornecidas para rotação, a configuração de assinatura rotada mais recente é usada. Antes da introdução da v3.1, a v3 só incluía essa configuração de assinatura rotativa mais recente. Assim, a v4 podia usar essa configuração como está. Com isso, o esquema de assinatura da v4 podia oferecer suporte à rotação, já que usava a chave de assinatura rotativa no SigningInfo. Embora o SigningInfo da v4 não inclua a linhagem de assinatura completa, ele pode extrair isso do bloco de assinatura da v3 para permitir que o acesso do plataforma à linhagem para todas as consultas de assinatura. Quando a v3.1 estiver em uso para segmentar a rotação da rotation-min-sdk-version fornecida, a configuração genérica da v3 vai incluir a configuração de assinatura original e a configuração de assinatura rotada mais recente. Uma extensão do esquema de assinatura v4 foi criada e inclui outros blocos de informações de assinatura para cada uma das configurações de assinatura do bloco v3.1.

Validação

Para testar a implementação da v3.1, execute os testes CTS PkgInstallSignatureVerificationTest.java em cts/hostsidetests/appsecurity/src/android/appsecurity/cts/.

Para mais informações sobre testes, consulte a seção verificação na v3.