Esquema de assinatura de APK v3.2

O Android 17 (nível 37 da API) apresenta o esquema de assinatura de APK v3.2, um esquema híbrido projetado para oferecer suporte à transição do ecossistema Android para a criptografia pós-quântica (PQC, na sigla em inglês).

À medida que o setor implanta algoritmos de PQC em grande escala, o esquema v3.2 oferece defesa em profundidade. Ele exige que você assine APKs com um algoritmo clássico, como RSA ou ECDSA, e um algoritmo de PQC. Essa abordagem híbrida usa a criptografia clássica para proteger o APK e se defender contra ameaças de computadores quânticos.

Objetivo e detalhes

O esquema v3.2 funciona como um mecanismo de transição padrão e alinhado ao setor. Com essa abordagem híbrida, você ganha os benefícios da PQC resistente a ataques quânticos, continuando a confiar na segurança comprovada dos algoritmos de assinatura clássicos. Depois que os algoritmos de PQC recém-padronizados estabelecerem maturidade operacional em grande escala, você poderá fazer a transição dessa configuração híbrida para uma única chave de assinatura de PQC. O suporte da plataforma para o esquema de assinatura v3.2 começa com o Android 17. As versões mais antigas do Android ignoram o bloco v3.2 e usam esquemas anteriores para verificação de assinatura.

Para manter a segurança e evitar ataques de downgrade durante essa transição, o esquema v3.2 impõe os seguintes comportamentos:

  • Novo material de chave:a transição para um bloco híbrido exige a geração de novas chaves clássicas e de PQC. Não reutilize o material de chave entre configurações híbridas e não híbridas.
  • Rotação implícita:a plataforma trata o bloco híbrido como uma rotação de chave implícita. A plataforma anexa a nova chave clássica à linhagem de assinatura atual do app como a penúltima chave e trata a nova chave de PQC como a identidade de assinatura atual do app.
  • Linhagem compartilhada:para executar a rotação implícita, a nova chave clássica e a nova chave de PQC no bloco híbrido precisam compartilhar a mesma ancestralidade de assinatura. Você precisa duplicar o histórico de assinatura atual do app, seja uma única chave original ou uma linhagem de chaves rotacionadas anteriormente, para os dois novos signatários híbridos. A plataforma usa essa linhagem compartilhada para verificar se a entidade que está fazendo a transição do app para o esquema híbrido é o proprietário legítimo da identidade de assinatura atual do app.
  • Restrição de signatário único de PQC:durante o lançamento inicial da PQC, o Android restringe explicitamente o uso de algoritmos de PQC ao bloco híbrido v3.2. A plataforma não verifica uma configuração de PQC de signatário único usando esquemas de assinatura anteriores, como v2, v3.0 ou v3.1.
  • Transição de volta:ao fazer a transição de um bloco híbrido v3.2 de volta para um bloco de signatário único, seja um signatário clássico ou um signatário de PQC quando compatível em uma versão futura, a plataforma verifica se as chaves clássicas e de PQC do bloco híbrido estão presentes na nova linhagem de assinatura e atestam o novo signatário único.

Práticas recomendadas para a transição

Para manter a compatibilidade com versões mais antigas do Android e fornecer um caminho de upgrade seguro durante a transição para a assinatura de PQC, os APKs precisam continuar incluindo um bloco de assinatura v3.0 ou v3.1 padrão assinado por uma única chave clássica. Como apenas o Android 17 (nível 37 da API) e versões mais recentes oferecem suporte ao esquema híbrido v3.2, esse requisito permite que dispositivos com versões mais antigas verifiquem e instalem o app.

Configuração de fallback clássica

Para fornecer uma rede de segurança operacional durante a transição de PQC, implemente uma configuração de fallback clássica.

  • Apps atuais:a chave de assinatura estabelecida atual do app, K0, serve como base natural para esse fallback.
  • Novos apps:gere uma chave de assinatura clássica de linha de base, K0, junto com as novas chaves híbridas, C_K1 e PQC_K1, para estabelecer a identidade inicial.

Nos dois cenários, o APK precisa incluir um bloco de assinatura v3.0 ou v3.1 padrão assinado pela chave clássica, K0, junto com o bloco híbrido v3.2 assinado pelas novas chaves híbridas, C_K1 e PQC_K1.

Durante a implantação inicial do esquema v3.2, a linhagem de assinatura do bloco híbrido precisa conceder a capacidade ROLLBACK a K0. Se surgirem problemas de implantação, essa capacidade permitirá que o app volte para uma assinatura clássica sem interromper as atualizações do usuário. Depois que dados de execução suficientes confirmarem que a implantação híbrida está estável, recomendamos remover a capacidade ROLLBACK em atualizações subsequentes para proteger totalmente suas novas chaves.

Requisitos de configuração de longo prazo

Você precisa manter essa configuração de assinatura híbrida enquanto o app for destinado a uma versão da plataforma que oferece suporte exclusivo ao esquema híbrido. Mesmo que uma versão da plataforma ofereça suporte a chaves de PQC de signatário único, você precisa assinar qualquer APK destinado a uma versão que exija o bloco híbrido v3.2 com as duas chaves.

Bloco do esquema de assinatura de APK v3.2

O bloco de assinatura de APK armazena o bloco de assinatura v3.2 junto com os blocos de assinatura v2, v3.0 e v3.1.

A estrutura do bloco v3.2 é semelhante à v3.0, mas usa um novo ID de bloco, 0x70e1c89f, para indicar que é um bloco híbrido. Um bloco v3.2 válido precisa conter exatamente dois signatários.

Algoritmos com suporte

O esquema v3.2 oferece suporte inicial aos seguintes algoritmos de assinatura de PQC:

  • ML-DSA-65
  • ML-DSA-87

Eles são pareados com algoritmos de assinatura clássicos padrão, como os compatíveis com v3.0 e v3.1, para formar o bloco híbrido.

Formato

O bloco de assinatura de APK armazena o bloco do esquema de assinatura de APK v3.2 no ID 0x70e1c89f.

O formato do bloco v3.2 é idêntico ao v3.0, mas a sequência de nível superior de elementos de signatário precisa conter exatamente duas entradas destinadas à mesma versão do SDK:

  • sequência com prefixo de comprimento do signatário com prefixo de comprimento:
    • signatário com prefixo de comprimento (clássico)
    • signatário com prefixo de comprimento (PQC)

Cada signatário usa o formato v3 padrão:

  • dados assinados com prefixo de comprimento:
    • sequência com prefixo de comprimento de resumos com prefixo de comprimento:
    • ID do algoritmo de assinatura (4 bytes)
    • resumo (com prefixo de comprimento)
    • sequência de certificados com prefixo de comprimento:
    • certificado X.509 com prefixo de comprimento (formulário ASN.1 DER)
    • minSDK (uint32)
    • maxSDK (uint32)
    • sequência com prefixo de comprimento de atributos adicionais com prefixo de comprimento:
    • ID (uint32)
    • valor (comprimento variável: comprimento do atributo adicional - 4 bytes)
  • minSDK (uint32)
  • maxSDK (uint32)
  • sequência com prefixo de comprimento de assinaturas com prefixo de comprimento:
    • ID do algoritmo de assinatura (4 bytes)
    • assinatura com prefixo de comprimento sobre dados assinados
  • chave pública com prefixo de comprimento (SubjectPublicKeyInfo, formulário ASN.1 DER)

Verificação

No Android 17 (nível 37 da API) e versões mais recentes, para verificar a assinatura v3.2, a plataforma verifica os signatários clássicos e de PQC, confirma a compatibilidade deles e verifica a linhagem de rotação implícita. No Android 16 (nível 36 da API) e versões mais antigas da plataforma, a plataforma não processa esse bloco de assinatura híbrida e usa esquemas anteriores.

O processo geral é o seguinte:

  1. Encontre o bloco do esquema de assinatura de APK v3.2 (ID 0x70e1c89f).
  2. Verifique se o bloco contém exatamente dois signatários. Se houver menos ou mais de dois, a verificação falhará.
  3. Verifique se um signatário usa um algoritmo de assinatura clássico e o outro usa um algoritmo de assinatura de PQC. Se ambos forem clássicos ou ambos forem de PQC, a verificação falhará.
  4. Verifique se os dois signatários são destinados ao mesmo intervalo de SDK (minSdkVersion e maxSdkVersion).
  5. Para cada um dos dois signatários, realize a verificação v3 padrão:
    1. Escolha o ID do algoritmo de assinatura com suporte mais forte nas assinaturas.
    2. Verifique a assinatura correspondente das assinaturas em relação aos dados assinados usando a chave pública.
    3. Verifique se o minSdkVersion e o maxSdkVersion nos dados assinados correspondem ao minSdkVersion e ao maxSdkVersion não assinados.
    4. Analise os certificados e verifique se o primeiro certificado corresponde à chave pública.
    5. Analise atributos adicionais para extrair estruturas de prova de rotação.
  6. Verifique o histórico de assinatura (prova de rotação):
    1. Verifique se os dois signatários têm históricos de assinatura anteriores idênticos.
    2. Os comprimentos da linhagem precisam corresponder, e todos os certificados e flags de capacidade que levam aos signatários atuais precisam ser idênticos.
    3. Se os históricos corresponderem, mescle as linhagens: trate o certificado do signatário clássico como o predecessor do certificado do signatário de PQC, atribuindo o signatário de PQC como o nó terminal atual.
  7. Verifique os resumos de conteúdo:
    1. Itere pelo mapa de resumos dos dois signatários.
    2. Verifique se, para algoritmos de resumo correspondentes, os valores de resumo calculados são idênticos entre os signatários clássicos e de PQC.
  8. Use os resumos correspondentes dos signatários verificados para verificar a integridade do conteúdo do APK (semelhante a v2 e v3).
    1. Se o app já estiver instalado, verifique a linhagem de atualização do pacote:
    2. Atualização de um único signatário: se o app instalado foi assinado com uma única chave clássica, essa chave precisa estar presente na linhagem de assinatura do novo bloco híbrido como um predecessor dos signatários híbridos.
    3. Atualização de um signatário híbrido para continuar híbrido: se o app instalado foi assinado com um bloco híbrido v3.2, as chaves clássicas e de PQC anteriores precisam permanecer como os signatários ativos atuais no bloco v3.2 do APK de atualização ou precisam estar presentes na nova linhagem de assinatura que atesta as chaves híbridas recém-rotacionadas.
    4. Transição de um signatário híbrido: se o app instalado foi assinado com um bloco híbrido v3.2 e o APK de atualização faz a transição de volta para um único signatário (PQC ou clássico), os dois signatários híbridos anteriores precisam estar presentes na linhagem de assinatura do APK de atualização e atestar a nova chave de assinatura única.
    5. Caminhos de atualização inválidos: se um desenvolvedor tentar atualizar um app assinado de forma híbrida usando apenas uma das chaves híbridas como um único signatário sem uma rotação adequada, a atualização falhará. As duas chaves precisam estar explicitamente envolvidas em qualquer transição para evitar ataques de downgrade.
  9. Se qualquer etapa falhar, a verificação falhará.

Proteção contra remoção

Para evitar ataques de downgrade a esquemas de assinatura mais antigos, o esquema v3.2 inclui atributos de proteção contra remoção semelhantes a iterações de esquema anteriores.

A ferramenta de assinatura grava dois atributos de proteção contra remoção híbrida específicos nos atributos adicionais dos blocos de assinatura v3.0 e v3.1. Esses atributos definem os limites exatos da versão do SDK em que o bloco híbrido v3.2 precisa estar presente e verificado:

  • Atributo de versão mínima do SDK (ID 0xbf940529): O valor desse atributo determina a versão mínima do SDK com suporte do bloco de assinatura híbrida.
  • Atributo de versão máxima do SDK (ID 0x9f06b79c): o valor desse atributo determina a versão máxima do SDK com suporte do bloco de assinatura híbrida. Esse atributo permite que você faça a transição para uma configuração de signatário único quando versões mais recentes da plataforma não exigem a assinatura híbrida.

Se a plataforma ignorar a verificação v3.2 porque o bloco está ausente ou o intervalo do SDK não se aplica ao dispositivo, a plataforma verificará o APK no próximo bloco presente. Se esse bloco anterior contiver esses atributos de proteção contra remoção, a plataforma aplicará as seguintes verificações:

  • Verificação de presença e intervalo:se um bloco de assinatura v3.0 ou v3.1 contiver o atributo de SDK mínimo (ID 0xbf940529, valor X) ou o atributo de SDK máximo (ID 0x9f06b79c, valor Y), a plataforma exigirá que o bloco híbrido v3.2 exista no APK. A plataforma lê o bloco híbrido para verificar se o intervalo de SDK de destino corresponde aos limites especificados por esses atributos. Se o bloco v3.2 estiver ausente ou se os valores de destino mínimo e máximo do SDK interno não forem iguais a X e Y, a plataforma rejeitará a instalação.
  • Imposição dentro do intervalo: se a versão do SDK do dispositivo estiver dentro do intervalo válido especificado por esses atributos, que é maior ou igual a X e menor ou igual a Y quando você fornece o atributo máximo, a plataforma exige estritamente o bloco híbrido v3.2 para verificação de assinatura. Se a plataforma verificar um bloco v3.0 ou v3.1 em um dispositivo dentro desse intervalo de SDK de destino, ela rejeitará a instalação porque o bloco v3.2 foi ignorado ou removido maliciosamente.

Ao impor esses limites, a plataforma determina quando um APK precisa conter um bloco v3.2. Se o bloco tiver sido removido, a plataforma rejeitará a instalação para evitar um ataque de downgrade.

Validar a implementação

Para testar a implementação do esquema de assinatura v3.2, execute os testes CTS HybridSignatureVerificationTest.java localizados em cts/hostsidetests/appsecurity/src/android/appsecurity/cts/.

Esses testes abrangem um conjunto abrangente de cenários, incluindo instalações bem-sucedidas, atualizações de versões somente clássicas, transições de reversão usando a capacidade ROLLBACK e verificações de mitigações de ataques de remoção.