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 v4

O Android 11 oferece suporte a um esquema de assinatura compatível com streaming com o APK Signature Scheme v4. A assinatura v4 é baseada na árvore hash Merkle calculada sobre todos os bytes do APK. Ele segue exatamente a estrutura da árvore hash fs-verity (por exemplo, preenchimento de zeros no salt e zeros no último bloco). O Android 11 armazena a assinatura em um arquivo separado, <apk name>.apk.idsig Uma assinatura v4 requer uma assinatura v2 ou v3 complementar.

Formato de arquivo

Todos os campos numéricos estão em little endian. Todos os campos ocupam exatamente o número de bytes de seu sizeof() , sem preenchimento ou alinhamento implícito adicionado.

Abaixo está uma estrutura auxiliar para simplificar as definições.

template <class SizeT>
struct sized_bytes {
        SizeT size;
        byte bytes[size];
};

Conteúdo do arquivo principal:

struct V4Signature {
        int32 version; // only version 2 is supported as of now
        sized_bytes<int32> hashing_info;
        sized_bytes<int32> signing_info;
        sized_bytes<int32> merkle_tree;  // optional
};

hashing_info são os parâmetros usados ​​para geração de árvore de hash + hash de raiz:

struct hashing_info.bytes {
    int32 hash_algorithm;    // only 1 == SHA256 supported
    int8 log2_blocksize;     // only 12 (block size 4096) supported now
    sized_bytes<int32> salt; // used exactly as in fs-verity, 32 bytes max
    sized_bytes<int32> raw_root_hash; // salted digest of the first Merkle tree page
};

signing_info é a seguinte estrutura:

struct signing_info.bytes {
    sized_bytes<int32> apk_digest;  // used to match with the corresponding APK
    sized_bytes<int32> x509_certificate; // ASN.1 DER form
    sized_bytes<int32> additional_data; // a free-form binary data blob
    sized_bytes<int32> public_key; // ASN.1 DER, must match the x509_certificate
    int32 signature_algorithm_id; // see the APK v2 doc for the list
    sized_bytes<int32> signature;
};
  • apk_digest é obtido do bloco de assinatura v3 do APK ou, se não estiver presente, do bloco v2 (consulte apk_digest )

Para criar e verificar um código de signature , é necessário serializar os seguintes dados em um blob binário e passá-los para o algoritmo de assinatura / verificação como os dados assinados :

struct V4DataForSigning {
        int32 size;
        int64 file_size; // the size of the file that's been hashed.
        hashing_info.hash_algorithm;
        hashing_info.log2_blocksize;
        hashing_info.salt;
        hashing_info.raw_root_hash;
        signing_info.apk_digest;
        signing_info.x509_certificate;
        signing_info.additional_data;
};
  1. merkle_tree é toda a árvore Merkle do APK, calculada conforme descrito na documentação do fs-verity .

Produtores e consumidores

apksigner ferramenta apksigner Android SDK agora gera o arquivo de assinatura v4 se você executá-lo com parâmetros padrão. A assinatura v4 pode ser desativada da mesma maneira que os outros esquemas de assinatura. Ele também pode verificar se a assinatura v4 é válida.

adb espera que o arquivo .apk.idsig esteja presente próximo ao .apk ao executar o comando adb install --incremental
Ele também usará o arquivo .idsig para tentar a instalação incremental por padrão e voltará para uma instalação normal se estiver ausente ou inválida.

Quando uma sessão de instalação é criada, a nova API de instalação de streaming no PackageInstaller aceita a assinatura v4 removida como um argumento separado ao adicionar um arquivo à sessão. Nesse ponto, a signing_info é passada para o incfs como um blob inteiro. Incfs extrai o hash raiz do blob.

Quando a sessão de instalação está sendo confirmada, PackageManagerService executa um ioctl para recuperar o blob xing_info do incfs, analisa-o e verifica a assinatura.

O componente Incremental Data Loader deve transmitir a parte da árvore Merkle da assinatura por meio da API nativa do carregador de dados.
package serviço shell comando install-incremental aceita o arquivo de assinatura v4 despojado codificado como base64 como um parâmetro para cada arquivo adicionado. A árvore Merkle correspondente deve ser enviada para o stdin do comando.

apk_digest

apk_digest é o primeiro resumo de conteúdo disponível em ordem:

  1. V3, bloco de 1 MB, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512),
  2. V3, bloco de 4 KB, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256),
  3. V3, bloco de 1 MB, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256),
  4. V2, SHA2-512,
  5. V2, SHA2-256.

Consulte a sequência com prefixo de comprimento de assinaturas com prefixo de comprimento no APK Signature Scheme v3.

Processo de validação do apk v4
Figura 1 : processo de validação de APK v4

Validação e teste

Valide a implementação usando testes de unidade de recurso e CTS.

  • CtsIncrementalInstallHostTestCases
    • / android / cts / hostsidetests / incrementalinstall

Testando o formato da assinatura

Para testar o formato da assinatura, configure um ambiente de desenvolvimento e execute os seguintes testes manuais:

$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest

Testando formato de assinatura com Android SDK (ADB e apksigner)

Para testar o formato da assinatura com Android SDK, configure um ambiente de desenvolvimento e certifique-se de ter concluído a implementação do IncFS . Em seguida, atualize a compilação em um dispositivo físico ou emulador de destino. Você precisa gerar ou obter um APK existente e, em seguida, criar uma chave de assinatura de depuração . Por fim, assine e instale o apk com formato de assinatura v4 da pasta de ferramentas de construção.

Placa

$ ./apksigner sign --ks debug.keystore game.apk

Instalar

$ ./adb install game.apk

Onde esses testes podem ser encontrados?

/android/cts/tests/tests/content/src/android/content/pm/cts/PackageManagerShellCommandIncrementalTest.java