O Android 11 oferece suporte a um esquema de assinatura compatível com streaming com o APK
Esquema de assinatura v4. A assinatura v4 é baseada na árvore de hash Merkle
calculada sobre todos os bytes do APK. Ele segue exatamente a estrutura da árvore de hash fs-verity (por exemplo, preenchimento com zero).
o sal e o preenchimento zero do último bloco). O Android 11 armazena a assinatura
em um arquivo separado, <apk name>.apk.idsig
assinatura A v4
requer uma assinatura v2 ou v3 complementar.
Formato do arquivo
Todos os campos numéricos estão em small endian. Todos os campos ocupam exatamente o número
como sizeof()
, sem padding implícito ou
alinhamento.
Veja abaixo um struct 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 a árvore de hash;
geração + o hash 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
é o seguinte struct:
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; };
- O
apk_digest
é extraído do bloco de assinatura v3 do APK ou, caso contrário, presente, a partir do bloco v2 (consulte apk_digest)
Para criar e verificar, um código signature
precisa serializar
os dados a seguir no 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; };
merkle_tree
é a árvore inteira do Merkle do APK, calculada conforme descrito na documentação de fs-verity.
Produtores e consumidores
apksigner
A ferramenta Android SDK agora gera o arquivo de assinatura v4
se 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álidos.
O adb
espera que o arquivo .apk.idsig esteja presente ao lado do .apk quando
executando o comando adb install --incremental
Ela também usará o arquivo .idsig para experimentar a instalação incremental
padrão e voltará a uma instalação normal se estiver ausente ou
inválido.
Quando uma sessão de instalação é criada, a nova API de instalação de streaming
no PackageInstaller
aceita as retiradas
assinatura v4 como um argumento separado ao adicionar um arquivo à sessão.
Neste ponto, signing_info
é transmitido para incfs como uma
todo o blob. O Incfs extrai o hash raiz do blob.
Quando a sessão de instalação está sendo confirmada, o PackageManagerService faz um ioctl para recuperar o blob de subscription_info de incfs, analisá-lo e verificá-lo a assinatura.
Espera-se que o componente incremental do carregador de dados transmita a parte da árvore Merkle
da assinatura pela API nativa do carregador de dados.
Comando install-incremental
do shell de serviço package
aceita o arquivo de assinatura v4 retirado codificado como base64 como parâmetro para cada
arquivo adicionado. A árvore do Merkle correspondente deve ser enviada para o diretório
stdin
:
apk_digest
apk_digest
é o primeiro resumo de conteúdo disponível em ordem:
- V3, bloco de 1 MB, SHA2-512 (CONTENT_DIGEST_CHUNKED_SHA512),
- V3, bloco de 4 KB, SHA2-256 (CONTENT_DIGEST_VERITY_CHUNKED_SHA256),
- V3, bloco de 1 MB, SHA2-256 (CONTENT_DIGEST_CHUNKED_SHA256),
- V2, SHA2-512
- V2, SHA2-256.
Consulte com prefixo de comprimento sequência de assinaturas com prefixo de comprimento no esquema de assinatura de APK v3.
Validação e teste
Validar a implementação usando testes de unidade de atributos e CTS.
CtsIncrementalInstallHostTestCases
- /android/cts/hostsidetests/incrementalinstall
Como testar o formato da assinatura
Para testar o formato de assinatura, configure em um ambiente de desenvolvimento e execute os seguintes testes manuais:
$ atest PackageManagerShellCommandTest
PackageManagerShellCommandIncrementalTest
Como testar o formato de assinatura com o SDK do Android (adb e apksigner)
Para testar o formato da assinatura com o SDK do Android, configure um ambiente de desenvolvimento. e garantir que você concluiu a implementação do IncFS (em inglês). Em seguida, atualize o build em um emulador ou dispositivo físico de destino. Você precisa para gerar ou acessar um APK existente e criar uma chave de assinatura de depuração. Por fim, assine e instale o apk com o formato de assinatura v4. da pasta build-tools.
Assinar
$ ./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