O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.
Esta página foi traduzida pela API Cloud Translation.
Switch to English

Esquema de assinatura APK v3

O Android 9 oferece suporte à rotação de chaves do APK , o que dá aos apps a capacidade de alterar sua chave de assinatura como parte de uma atualização do APK. Para tornar a rotação prática, os APKs devem indicar níveis de confiança entre a chave de assinatura nova e a antiga. Para oferecer suporte à rotação de chaves, atualizamos o esquema de assinatura do APK de v2 para v3 para permitir que as chaves novas e antigas sejam usadas. A V3 adiciona informações sobre as versões do SDK com suporte e uma estrutura de prova de rotação ao bloco de assinatura do APK.

Bloco de assinatura de APK

Para manter a compatibilidade com versões anteriores com o formato APK v1, as assinaturas de APK v2 e v3 são armazenadas dentro de um bloco de assinatura de APK, localizado imediatamente antes do diretório central ZIP.

O formato do bloco de assinatura do APK v3 é o mesmo da v2 . A assinatura v3 do APK é armazenada como um par de valor de ID com ID 0xf05368c0.

Bloco de esquema v3 de assinatura de APK

O esquema v3 foi projetado para ser muito semelhante ao esquema v2 . Ele tem o mesmo formato geral e suporta os mesmos IDs de algoritmo de assinatura , tamanhos de chave e curvas EC.

No entanto, o esquema v3 adiciona informações sobre as versões do SDK com suporte e a estrutura de prova de rotação.

Formato

O bloco v3 do esquema de assinatura do APK é armazenado dentro do bloco de assinatura do APK com o ID 0xf05368c0 .

O formato do bloco v3 do esquema de assinatura do APK segue o da v2:

  • sequência prefixada de comprimento do signer prefixado por comprimento:
    • signed data prefixo de comprimento:
      • sequência prefixada de comprimento de digests prefixados por comprimento:
        • signature algorithm ID (4 bytes)
        • digest (prefixado por comprimento)
      • sequência com prefixo de comprimento de certificates X.509:
        • certificate X.509 com prefixo de comprimento (formato ASN.1 DER)
      • minSDK (uint32) - este signatário deve ser ignorado se a versão da plataforma estiver abaixo desse número.
      • maxSDK (uint32) - este signatário deve ser ignorado se a versão da plataforma estiver acima deste número.
      • sequência com prefixo de comprimento de additional attributes prefixo de comprimento:
        • ID (uint32)
        • value (comprimento variável: comprimento do atributo adicional - 4 bytes)
        • ID - 0x3ba06f8c
        • value - prova de rotação
    • minSDK (uint32) - duplicata do valor minSDK na seção de dados assinados - usado para pular a verificação desta assinatura se a plataforma atual não estiver no intervalo. Deve corresponder ao valor dos dados assinados.
    • maxSDK (uint32) - duplicata do valor maxSDK na seção de dados assinados - usado para pular a verificação desta assinatura se a plataforma atual não estiver no intervalo. Deve corresponder ao valor dos dados assinados.
    • sequência prefixada de comprimento de signatures prefixadas por comprimento:
      • signature algorithm ID (uint32)
      • signature prefixo de comprimento sobre signed data
    • public key prefixo de comprimento (SubjectPublicKeyInfo, formato ASN.1 DER)

Estruturas de prova de rotação e autoconfiantes-velhos-certs

A estrutura de prova de rotação permite que os aplicativos girem seu certificado de assinatura sem serem bloqueados em outros aplicativos com os quais se comunicam. Para fazer isso, as assinaturas de aplicativos contêm dois novos dados:

  • afirmação para terceiros de que o certificado de assinatura do aplicativo pode ser confiável onde quer que seus antecessores sejam confiáveis
  • certificados de assinatura mais antigos do aplicativo, nos quais o próprio aplicativo ainda confia

O atributo de prova de rotação na seção de dados assinados consiste em uma lista vinculada individualmente, com cada nó contendo um certificado de assinatura usado para assinar versões anteriores do aplicativo. Esse atributo deve conter as estruturas de dados conceituais de prova de rotação e certificados antigos autoconfiáveis. A lista é ordenada por versão com o certificado de assinatura mais antigo correspondendo ao nó raiz. A estrutura de dados de prova de rotação é construída fazendo com que o certificado em cada nó assine o próximo na lista e, assim, imbuindo cada nova chave com evidências de que ela deve ser tão confiável quanto a (s) chave (s) antiga (s).

A estrutura de dados self-trusted-old-certs é construída adicionando sinalizadores a cada nó, indicando sua associação e propriedades no conjunto. Por exemplo, um sinalizador pode estar presente indicando que o certificado de assinatura em um determinado nó é confiável para obter permissões de assinatura Android. Este sinalizador permite que outros aplicativos assinados pelo certificado mais antigo ainda recebam uma permissão de assinatura definida por um aplicativo assinado com o novo certificado de assinatura. Como todo o atributo de prova de rotação reside na seção de dados assinados do campo do signer v3, ele é protegido pela chave usada para assinar o apk contido.

Esse formato impede várias chaves de assinatura e a convergência de diferentes certificados de assinatura ancestrais em um (vários nós iniciais para um coletor comum).

Formato

A prova de rotação é armazenada dentro do bloco v3 do esquema de assinatura APK sob ID 0x3ba06f8c . Seu formato é:

  • sequência de comprimento prefixado de levels prefixados de comprimento:
    • signed data prefixo de comprimento (por certificado anterior - se houver)
      • certificate X.509 com prefixo de comprimento (formato ASN.1 DER)
      • signature algorithm ID (uint32) - algoritmo usado pelo cert no nível anterior
    • flags (uint32) - sinalizadores que indicam se este certificado deve ou não estar na estrutura self-trust-old-certs e para quais operações.
    • signature algorithm ID (uint32) - deve corresponder ao da seção de dados assinados no próximo nível.
    • signature prefixo de comprimento sobre os signed data acima

Certificados múltiplos

O Android atualmente trata um APK assinado com vários certificados como tendo uma identidade de assinatura única separada dos certificados que o abrangem. Assim, o atributo de prova de rotação na seção de dados assinados forma um gráfico acíclico direcionado, que poderia ser melhor visualizado como uma lista unida por unidade, com cada conjunto de signatários para uma determinada versão representando um nó. Isso adiciona complexidade extra à estrutura de prova de rotação (versão com vários assinantes abaixo). Em particular, o pedido torna-se uma preocupação. Além do mais, não é mais possível assinar APKs de forma independente, porque a estrutura de prova de rotação deve ter os certificados de assinatura antigos assinando o novo conjunto de certificados, em vez de assiná-los um por um. Por exemplo, um APK assinado pela chave A que deseja ser assinado por duas novas chaves B e C não pode ter o signatário B apenas incluindo uma assinatura de A ou B, porque essa é uma identidade de assinatura diferente de B e C. significa que os signatários devem coordenar antes de construir tal estrutura.

Atributo de prova de rotação de vários signatários

  • sequência prefixada de comprimento de sets prefixados por comprimento:
    • signed data (pelo conjunto anterior - se houver)
      • sequência de certificates com prefixo de comprimento
        • certificate X.509 com prefixo de comprimento (formato ASN.1 DER)
      • Sequência de signature algorithm IDs de signature algorithm IDs (uint32) - um para cada certificado do conjunto anterior, na mesma ordem.
    • flags (uint32) - sinalizadores que indicam se este conjunto de certificados deve ou não estar na estrutura self-trust-old-certs e para quais operações.
    • sequência com prefixo de comprimento de signatures prefixo de comprimento:
      • signature algorithm ID (uint32) - deve corresponder ao da seção de dados assinados
      • signature prefixo de comprimento sobre os signed data acima

Vários ancestrais na estrutura de prova de rotação

O esquema v3 também não lida com duas chaves diferentes girando para a mesma chave de assinatura para o mesmo aplicativo. Isso difere do caso de uma aquisição, em que a empresa adquirente gostaria de mover o aplicativo adquirido para usar sua chave de assinatura para compartilhar permissões. A aquisição é vista como um caso de uso com suporte porque o novo aplicativo seria diferenciado por seu nome de pacote e poderia conter sua própria estrutura de prova de rotação. O caso sem suporte, de o mesmo aplicativo ter dois caminhos diferentes para chegar ao mesmo certificado, quebra muitas das suposições feitas no design de rotação de chave.

Verificação

No Android 9 e superior, os APKs podem ser verificados de acordo com o esquema de assinatura APK v3, esquema v2 ou esquema v1. As plataformas mais antigas ignoram as assinaturas da v3 e tentam verificar as assinaturas da v2 e, em seguida, da v1.

Processo de verificação de assinatura de APK

Figura 1. Processo de verificação de assinatura de APK

Verificação do esquema de assinatura do APK v3

  1. Localize o bloco de assinatura do APK e verifique se:
    1. Dois campos de tamanho de APK Signing Block contêm o mesmo valor.
    2. O ZIP Central Directory é imediatamente seguido pelo ZIP End of Central Directory record.
    3. ZIP Fim do diretório central não é seguido por mais dados.
  2. Localize o primeiro bloco do esquema de assinatura v3 do APK dentro do bloco de assinatura do APK. Se o bloco v3 estiver presente, prossiga para a etapa 3. Caso contrário, volte a verificar o APK usando o esquema v2 .
  3. Para cada signer no bloco v3 do esquema de assinatura APK com uma versão mínima e máxima do SDK que está no intervalo da plataforma atual:
    1. Escolha o signature algorithm ID de signatures mais forte com suporte nas signatures . A ordenação de força depende de cada versão de implementação / plataforma.
    2. Verifique a signature correspondente das signatures relação aos signed data usando public key . (Agora é seguro analisar os signed data .)
    3. Verifique se as versões mínimas e máximas do SDK nos dados assinados correspondem às especificadas para o signer .
    4. Verifique se a lista ordenada de IDs de algoritmo de assinatura em digests e signatures é idêntica. (Isso evita a remoção / adição de assinaturas.)
    5. Calcule o resumo do conteúdo do APK usando o mesmo algoritmo de resumo usado pelo algoritmo de assinatura.
    6. Verifique se o resumo calculado é idêntico ao digest correspondente dos digests .
    7. Verifique se SubjectPublicKeyInfo do primeiro certificate de certificates é idêntico à public key .
    8. Se o atributo de prova de rotação existir para o signer verifique se a estrutura é válida e se esse signer é o último certificado da lista.
  4. A verificação será bem-sucedida se exatamente um signer for encontrado no intervalo da plataforma atual e a etapa 3 for bem-sucedida para esse signer .

Validação

Para testar se o seu dispositivo suporta v3 corretamente, execute os testes PkgInstallSignatureVerificationTest.java CTS em cts/hostsidetests/appsecurity/src/android/appsecurity/cts/ .