Android 9 suporta APK rotação da chave , que dá aplicativos a capacidade de alterar a sua chave de assinatura como parte de uma atualização 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 apoiar a rotação da chave, atualizamos o esquema de assinatura APK de v2 para v3 para permitir que as teclas de novos e antigos para ser usado. 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 APK v3 assinatura formato de bloco é o mesmo que 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 é projetado para ser muito semelhante ao esquema de v2 . Ele tem o mesmo formato geral e suporta os mesmos IDs de assinatura algoritmo , tamanhos chave, e as curvas da CE.
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
APK Assinatura Esquema v3 bloco é armazenado dentro da APK assinatura bloco sob ID 0xf05368c0
.
O formato do bloco v3 do esquema de assinatura do APK segue o da v2:
- sequência prefixo comprimento do prefixo de comprimento
signer
:- prefixo de comprimento
signed data
:- sequência prefixo comprimento do prefixo de comprimento
digests
:-
signature algorithm ID
(4 bytes) -
digest
(comprimento-prefixada)
-
- sequência prefixo de comprimento de X.509
certificates
:- de comprimento prefixo X.509
certificate
(forma ASN.1 DER)
- de comprimento prefixo X.509
-
minSDK
(uint32) - este signatário deve ser ignorado se a versão plataforma está abaixo deste número. -
maxSDK
(uint32) - este signatário deve ser ignorado se a versão plataforma é acima deste número. - sequência prefixo comprimento do prefixo de comprimento
additional attributes
:-
ID
(uint32) -
value
(comprimento variável: comprimento do atributo adicional - 4 bytes) -
ID - 0x3ba06f8c
-
value -
Prova de rotação struct
-
- sequência prefixo comprimento do prefixo de comprimento
-
minSDK
(uint32) - duplicado de valor minSDK na seção de dados assinado - usado para ignorar a verificação desta assinatura se a plataforma atual não está no intervalo. Deve corresponder ao valor dos dados assinados. -
maxSDK
(uint32) - duplicado do valor maxSDK na seção de dados assinado - usado para ignorar a verificação desta assinatura se a plataforma atual não está no intervalo. Deve corresponder ao valor dos dados assinados. - sequência prefixo comprimento do prefixo de comprimento
signatures
:-
signature algorithm ID
(uint32) - prefixo de comprimento
signature
sobresigned data
-
- prefixo-comprimento
public key
(SubjectPublicKeyInfo, ASN.1 DER forma)
- prefixo de comprimento
Estruturas de prova de rotação e autoconfiantes de velhos certificados
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:
- declaração para terceiros de que o certificado de assinatura do aplicativo pode ser confiável onde quer que seus predecessores 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. Este atributo destina-se a conter as estruturas de dados conceituais de prova de rotação e certificados antigos auto-confiá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) mais 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. Porque toda a prova de rotação reside atributo na seção de dados assinada do v3 signer
campo, ele é protegido pela chave usado para assinar o apk contendo.
Este formato se opõe várias chaves de assinatura e de convergência de diferentes certificados de assinatura ancestral para um (vários nós de partida para uma pia comum).
Formato
A rotação prova-de-são armazenados dentro da Assinatura APK Esquema v3 bloco sob ID 0x3ba06f8c
. Seu formato é:
- sequência prefixo comprimento do prefixo de comprimento
levels
:- prefixo de comprimento
signed data
(por cert anterior - se existir)- de comprimento prefixo X.509
certificate
(forma ASN.1 DER) -
signature algorithm ID
(uint32) - algoritmo usado pelo cert no nível anterior
- de comprimento prefixo X.509
-
flags
(uint32) - bandeiras que indicam se ou não este cert deve estar na estrutura de auto-confiança-old-certs, e para os quais as operações. -
signature algorithm ID
(uint32) - deve corresponder ao da seção de dados assinado no próximo nível. - de comprimento prefixado
signature
ao longo dos acimasigned data
- prefixo de comprimento
Certificados múltiplos
O Android atualmente trata um APK assinado com vários certificados como tendo uma identidade de assinatura exclusiva 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 visto 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 antigos certificados de assinatura 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 poderia 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 prefixo comprimento do prefixo de comprimento
sets
:-
signed data
(por conjunto anterior - se existir)- sequência prefixo de comprimento de
certificates
- de comprimento prefixo X.509
certificate
(forma ASN.1 DER)
- de comprimento prefixo X.509
- Sequência de
signature algorithm IDs
(uint32) - um para cada certificado do conjunto anterior, na mesma ordem.
- sequência prefixo de comprimento de
-
flags
(uint32) - bandeiras que indicam se ou não este conjunto de certificados deve ser na auto-confiança de idade,-certs struct, e para o qual as operações. - sequência prefixo comprimento do prefixo de comprimento
signatures
:-
signature algorithm ID
(uint32) - deve corresponder ao da seção de dados assinado - de comprimento prefixado
signature
ao longo dos acimasigned data
-
-
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.
Figura processo de verificação de assinatura 1. APK
Verificação do esquema de assinatura do APK v3
- Localize o bloco de assinatura do APK e verifique se:
- Dois campos de tamanho do bloco de assinatura do APK contêm o mesmo valor.
- O ZIP Central Directory é imediatamente seguido pelo ZIP End of Central Directory record.
- ZIP Fim do diretório central não é seguido por mais dados.
- Localize o primeiro bloco de esquema de assinatura de APK v3 dentro do bloco de assinatura de APK. Se o v3 Bloquear estiver presente, avance para o passo 3. Caso contrário, cair de volta para verificar o APK usando esquema de v2 .
- Para cada
signer
na assinatura APK Esquema v3 bloco com um min e versão SDK máxima que é na gama da plataforma de corrente:- Escolha o apoiou mais forte
signature algorithm ID
designatures
. A ordem de força depende de cada versão de implementação / plataforma. - Verifique a correspondente
signature
designatures
contrasigned data
utilizandopublic key
. (Agora é seguro para analisarsigned data
.) - Verificar as versões mínimo e máximo SDK nos dados assinados correspondem às especificado para o
signer
. - Verifique se a lista ordenada de IDs algoritmo assinatura em
digests
esignatures
é idêntico. (Isso evita a remoção / adição de assinaturas.) - Calcular o resumo do conteúdo APK usando o mesmo algoritmo de resumo como a digerir algoritmo usado pelo algoritmo de assinatura.
- Verifique se o digest calculado é idêntico ao correspondente
digest
dedigests
. - Verifique se SubjectPublicKeyInfo do primeiro
certificate
decertificates
é idêntica àpublic key
. - Se existe o atributo de prova de rotação para o
signer
verificar se a estrutura é válido e estesigner
é o último certificado na lista.
- Escolha o apoiou mais forte
- Verificação bem-sucedido se exatamente um
signer
foi encontrado na faixa da plataforma atual e passo 3 sucedido para essesigner
.
Validação
Para testar se o dispositivo suporta v3 corretamente, execute os PkgInstallSignatureVerificationTest.java
testes CTS em cts/hostsidetests/appsecurity/src/android/appsecurity/cts/
.