As imagens do SO Android usam assinaturas criptográficas em dois lugares:
- Cada arquivo
.apk
dentro da imagem precisa ser assinado. do Android. O Gerenciador de pacotes usa uma assinatura.apk
de duas maneiras:- Quando um aplicativo é substituído, ele deve ser assinado pela mesma chave do
aplicativo antigo para obter acesso aos dados do aplicativo antigo. Isso mantém
verdadeiro para atualizar apps do usuário substituindo
.apk
e para substituindo um app do sistema por uma versão mais recente instalada/data
. - Se dois ou mais aplicativos quiserem compartilhar um ID de usuário (para que possam compartilhar dados etc.), eles devem ser assinados com a mesma chave.
- Quando um aplicativo é substituído, ele deve ser assinado pela mesma chave do
aplicativo antigo para obter acesso aos dados do aplicativo antigo. Isso mantém
verdadeiro para atualizar apps do usuário substituindo
- Os pacotes de atualização OTA devem ser assinados com uma das chaves esperadas pelo ou o processo de instalação os rejeitará.
Chaves de lançamento
A árvore do Android inclui test-keys em
build/target/product/security
Como criar uma imagem do SO Android
usando make
assinará todos os arquivos .apk
usando a
chaves de teste. Como as chaves de teste são de conhecimento público, qualquer pessoa pode assinar as próprias chaves
.apk com as mesmas chaves, o que pode permitir que eles substituam ou sequestram o sistema.
integrados à imagem do SO. Por isso, é essencial assinar
imagem do SO Android lançada publicamente ou implantada com um conjunto especial de
release-keys às quais só você tem acesso.
Para gerar seu próprio conjunto exclusivo de chaves de lançamento, execute estes comandos em a raiz da sua árvore Android:
subject='/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/emailAddress=android@android.com'
mkdir ~/.android-certs
for x in releasekey platform shared media networkstack; do \ ./development/tools/make_key ~/.android-certs/$x "$subject"; \ done
Altere $subject
para refletir o valor da sua organização
informações imprecisas ou inadequadas. Você pode usar qualquer diretório, mas tenha cuidado para escolher
local seguro e armazenado em backup. Alguns fornecedores optam por criptografar
a chave privada com uma senha longa forte e armazenar a chave criptografada
no controle de origem, enquanto outros armazenam as chaves de lançamento em outro lugar,
como em um computador com isolamento físico.
Para gerar uma imagem de lançamento, use:
make dist
sign_target_files_apks \ -o \ # explained in the next section --default_key_mappings ~/.android-certs out/dist/*-target_files-*.zip \ signed-target_files.zip
O script sign_target_files_apks
usa um arquivo de destino
.zip
como entrada e produz um novo arquivo de destino .zip
em
na qual todos os arquivos .apk
foram assinados com novas chaves. A nova
imagens assinadas podem ser encontradas abaixo de IMAGES/
em
signed-target_files.zip
.
Assinar pacotes OTA
Um ZIP com arquivos de destino assinado pode ser convertido em um ZIP de atualização OTA assinado seguindo este procedimento:
ota_from_target_files \
-k (--package_key)
signed-target_files.zip \
signed-ota_update.zip
Assinaturas e sideload
O sideload não ignora a assinatura de pacote normal da recuperação mecanismo de verificação. Antes de instalar um pacote, a recuperação verifica se é assinado com uma das chaves privadas que correspondem às chaves públicas armazenadas em a partição de recuperação, assim como em um pacote entregue over-the-air.
Os pacotes de atualização recebidos do sistema principal costumam ser verificados duas vezes:
uma vez pelo sistema principal, usando o
RecoverySystem.verifyPackage()
um método na API do Android e, em seguida,
recuperação de desastres. A API RecoverySystem verifica a assinatura em relação a chaves públicas.
armazenado no sistema principal, no arquivo /system/etc/security/otacerts.zip
(por padrão). A recuperação verifica a assinatura em relação às chaves públicas armazenadas
no disco RAM da partição de recuperação, no arquivo /res/keys
.
Por padrão, os arquivos de destino .zip
produzidos pelo build definem o
certificado OTA para corresponder à chave de teste. Em uma imagem lançada, uma imagem
certificado deve ser usado para que os dispositivos possam verificar a autenticidade do
update. Transmitir a sinalização -o
para
sign_target_files_apks
, como mostrado na seção anterior, substitui
o certificado da chave de teste com o certificado da chave de lançamento dos seus certificados
diretório.
Normalmente, a imagem do sistema e a imagem de recuperação armazenam o mesmo conjunto de recursos OTA chaves públicas. Ao adicionar uma chave apenas ao conjunto de chaves de recuperação, possível assinar pacotes que só podem ser instalados por sideload (supondo que o mecanismo de download de atualização do sistema principal esteja funcionando corretamente verificação em relação a otacerts.zip). É possível especificar chaves extras para serem incluído apenas na recuperação ao configurar o atributo PRODUCT_EXTRA_RECOVERY_KEYS na definição do produto:
vendor/yoyodyne/tardis/products/tardis.mk
[...] PRODUCT_EXTRA_RECOVERY_KEYS := vendor/yoyodyne/security/tardis/sideload
Isso inclui a chave pública
vendor/yoyodyne/security/tardis/sideload.x509.pem
na recuperação
o arquivo de chaves para instalar pacotes assinados
a ele. A chave extra não está incluída no otacerts.zip. Portanto,
os sistemas que verificam corretamente os pacotes baixados não invocam a recuperação
pacotes assinados com essa chave.
Certificados e chaves privadas
Cada chave vem em dois arquivos: o certificado, que tem o extensão .x509.pem e a chave privada, que tem a extensão .pk8. A chave privada deve ser mantida em segredo e é necessária para assinar um pacote. A chave pode ser protegido por uma senha. O certificado, em contraste, contém apenas a metade pública da chave, para que possa ser distribuído muito mais. Ele é usado para verificar se um pacote foi assinado pelo chave privada.
O build padrão do Android usa cinco chaves, todas localizadas em
build/target/product/security
:
- chave de teste
- Chave padrão genérica para pacotes que não especificam chave de outra forma.
- plataforma
- Chave de teste para pacotes que fazem parte da plataforma principal.
- compartilhado
- Teste a chave para itens compartilhados no processo de casa/contatos.
- mídia
- Chave de teste para pacotes que fazem parte do sistema de mídia/download.
Pacotes individuais especificam uma dessas chaves definindo LOCAL_CERTIFICATE no arquivo Android.mk. A chave de teste será usada se a variável não estiver definida. Você também pode especificar uma chave totalmente diferente por nome de caminho, por exemplo:
device/yoyodyne/apps/SpecialApp/Android.mk
[...] LOCAL_CERTIFICATE := device/yoyodyne/security/special
Agora, o build usa a chave device/yoyodyne/security/special.{x509.pem,pk8}
para assinar o SpecialApp.apk. O build pode usar somente chaves privadas
não são protegidos por senha.
Opções de assinatura avançadas
Substituição da chave de assinatura do APK
O script de assinatura sign_target_files_apks
funciona no destino
arquivos gerados para um build. Todas as informações em certificados e políticas
As chaves usadas no tempo de build são incluídas nos arquivos de destino. Ao executar o comando
assinatura do script para lançamento, as chaves de assinatura podem ser substituídas com base na chave
ou o nome do APK.
Usar --key_mapping
e --default_key_mappings
para especificar a substituição de chaves com base nos nomes delas:
- A sinalização
--key_mapping src_key=dest_key
especifica a substituição de uma chave por vez. - A sinalização
--default_key_mappings dir
especifica um com cinco chaves para substituir todas as chaves nobuild/target/product/security
é equivalente a usar--key_mapping
cinco vezes para especificar os mapeamentos.
build/target/product/security/testkey = dir/releasekey build/target/product/security/platform = dir/platform build/target/product/security/shared = dir/shared build/target/product/security/media = dir/media build/target/product/security/networkstack = dir/networkstack
Use o
Sinalização --extra_apks apk_name1,apk_name2,...=key
para especificar as substituições de chave de assinatura com base nos nomes do APK. Se
key
for deixado em branco, o script tratará os APKs especificados
como pré-assinado.
Para o produto tardis hipotético, você precisa de seis chaves protegidas por senha:
cinco para substituir os cinco em build/target/product/security
e um
para substituir a chave adicional device/yoyodyne/security/special
exigido pela SpecialApp no exemplo acima. Se as chaves estivessem no seguinte
arquivos:
vendor/yoyodyne/security/tardis/releasekey.x509.pem vendor/yoyodyne/security/tardis/releasekey.pk8 vendor/yoyodyne/security/tardis/platform.x509.pem vendor/yoyodyne/security/tardis/platform.pk8 vendor/yoyodyne/security/tardis/shared.x509.pem vendor/yoyodyne/security/tardis/shared.pk8 vendor/yoyodyne/security/tardis/media.x509.pem vendor/yoyodyne/security/tardis/media.pk8 vendor/yoyodyne/security/tardis/networkstack.x509.pem vendor/yoyodyne/security/tardis/networkstack.pk8 vendor/yoyodyne/security/special.x509.pem vendor/yoyodyne/security/special.pk8 # NOT password protected vendor/yoyodyne/security/special-release.x509.pem vendor/yoyodyne/security/special-release.pk8 # password protected
Em seguida, você assinaria todos os apps desta forma:
./build/make/tools/releasetools/sign_target_files_apks \
--default_key_mappings vendor/yoyodyne/security/tardis \
--key_mapping vendor/yoyodyne/security/special=vendor/yoyodyne/security/special-release \
--extra_apks PresignedApp= \
-o tardis-target_files.zip \
signed-tardis-target_files.zip
Isso resulta no seguinte:
Enter password for vendor/yoyodyne/security/special-release key> Enter password for vendor/yoyodyne/security/tardis/networkstack key> Enter password for vendor/yoyodyne/security/tardis/media key> Enter password for vendor/yoyodyne/security/tardis/platform key> Enter password for vendor/yoyodyne/security/tardis/releasekey key> Enter password for vendor/yoyodyne/security/tardis/shared key> signing: Phone.apk (vendor/yoyodyne/security/tardis/platform) signing: Camera.apk (vendor/yoyodyne/security/tardis/media) signing: NetworkStack.apk (vendor/yoyodyne/security/tardis/networkstack) signing: Special.apk (vendor/yoyodyne/security/special-release) signing: Email.apk (vendor/yoyodyne/security/tardis/releasekey) [...] signing: ContactsProvider.apk (vendor/yoyodyne/security/tardis/shared) signing: Launcher.apk (vendor/yoyodyne/security/tardis/shared) NOT signing: PresignedApp.apk (skipped due to special cert string) rewriting SYSTEM/build.prop: replace: ro.build.description=tardis-user Eclair ERC91 15449 test-keys with: ro.build.description=tardis-user Eclair ERC91 15449 release-keys replace: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/test-keys with: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/release-keys signing: framework-res.apk (vendor/yoyodyne/security/tardis/platform) rewriting RECOVERY/RAMDISK/default.prop: replace: ro.build.description=tardis-user Eclair ERC91 15449 test-keys with: ro.build.description=tardis-user Eclair ERC91 15449 release-keys replace: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/test-keys with: ro.build.fingerprint=generic/tardis/tardis/tardis:Eclair/ERC91/15449:user/release-keys using: vendor/yoyodyne/security/tardis/releasekey.x509.pem for OTA package verification done.
Depois de solicitar senhas ao usuário de todas as chaves protegidas por senha, o
assina novamente todos os arquivos APK no destino de entrada .zip
com o
chaves de lançamento. Antes de executar o comando, também é possível definir a
ANDROID_PW_FILE
para um nome de arquivo temporário. as
script invoca seu editor para permitir que você digite as senhas de todas as chaves
Essa pode ser uma maneira mais conveniente de inserir senhas.
Substituição de chave de assinatura APEX
O Android 10 introduz a Formato de arquivo APEX para instalação módulos de sistema de nível inferior. Conforme explicado em Assinatura APEX, cada arquivo APEX é assinada com duas chaves: uma para a imagem do mini sistema de arquivos em um APEX e a para todo o APEX.
Ao assinar para lançamento, as duas chaves de assinatura de um arquivo APEX são substituídas
com as chaves de lançamento. A chave de payload do sistema de arquivos é especificada com o
A sinalização --extra_apex_payload
e toda a chave de assinatura do arquivo APEX serão
especificado com a sinalização --extra_apks
.
Para o produto tardis, suponha que você tenha a seguinte configuração de chave
para o com.android.conscrypt.apex
,
com.android.media.apex
e
com.android.runtime.release.apex
arquivos APEX.
name="com.android.conscrypt.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" name="com.android.media.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" name="com.android.runtime.release.apex" public_key="vendor/yoyodyne/security/testkeys/com.android.runtime.avbpubkey" private_key="vendor/yoyodyne/security/testkeys/com.android.runtime.pem" container_certificate="vendor/yoyodyne/security/testkeys/com.google.android.runtime.release_container.x509.pem" container_private_key="vendor/yoyodyne/security/testkeys/com.google.android.runtime.release_container.pk8"
E você tem os seguintes arquivos que contêm as chaves de lançamento:
vendor/yoyodyne/security/runtime_apex_container.x509.pem vendor/yoyodyne/security/runtime_apex_container.pk8 vendor/yoyodyne/security/runtime_apex_payload.pem
O comando a seguir substitui as chaves de assinatura de
com.android.runtime.release.apex
e
com.android.tzdata.apex
durante a assinatura da versão. Especificamente,
com.android.runtime.release.apex
está assinado com o
chaves de lançamento (runtime_apex_container
para o arquivo APEX e
runtime_apex_payload
para o payload da imagem do arquivo).
com.android.tzdata.apex
é tratado como pré-assinado. Todos os outros APEX
são processados pela configuração padrão, conforme listado nos arquivos de destino.
./build/make/tools/releasetools/sign_target_files_apks \
--default_key_mappings vendor/yoyodyne/security/tardis \
--extra_apks com.android.runtime.release.apex=vendor/yoyodyne/security/runtime_apex_container \
--extra_apex_payload_key com.android.runtime.release.apex=vendor/yoyodyne/security/runtime_apex_payload.pem \
--extra_apks com.android.media.apex= \
--extra_apex_payload_key com.android.media.apex= \
-o tardis-target_files.zip \
signed-tardis-target_files.zip
A execução do comando acima gera os seguintes registros:
[...] signing: com.android.runtime.release.apex container (vendor/yoyodyne/security/runtime_apex_container) : com.android.runtime.release.apex payload (vendor/yoyodyne/security/runtime_apex_payload.pem) NOT signing: com.android.conscrypt.apex (skipped due to special cert string) NOT signing: com.android.media.apex (skipped due to special cert string) [...]
Outras opções
O script de assinatura sign_target_files_apks
reescreve o build
descrição e impressão digital nos arquivos de propriedades do build para refletir que o
o build é assinado. A sinalização --tag_changes
controla quais edições são
na impressão digital. Execute o script com -h
para ver
a documentação sobre todas as sinalizações.
Gerar chaves manualmente
O Android usa chaves RSA de 2048 bits com expoente público 3. É possível gerar pares de certificado/chave privada usando a ferramenta openssl da openssl.org (em inglês):
# generate RSA keyopenssl genrsa -3 -out temp.pem 2048
Generating RSA private key, 2048 bit long modulus ....+++ .....................+++ e is 3 (0x3) # create a certificate with the public part of the keyopenssl req -new -x509 -key temp.pem -out releasekey.x509.pem -days 10000 -subj '/C=US/ST=California/L=San Narciso/O=Yoyodyne, Inc./OU=Yoyodyne Mobility/CN=Yoyodyne/emailAddress=yoyodyne@example.com'
# create a PKCS#8-formatted version of the private keyopenssl pkcs8 -in temp.pem -topk8 -outform DER -out releasekey.pk8 -nocrypt
# securely delete the temp.pem fileshred --remove temp.pem
O comando openssl pkcs8 fornecido acima cria um arquivo .pk8 com no
adequada para uso com o sistema de build. Para criar um arquivo .pk8 protegido
por uma senha (o que deve ser feito para todas as chaves de liberação reais), substitua o
argumento -nocrypt
com -passout stdin
; Depois, openssl
criptografará a chave privada com uma senha lida na entrada padrão. Não
é exibido. Portanto, se stdin for o terminal, o programa aparecerá travado
apenas esperando que você insira uma senha. Outros valores podem ser
usado como argumento-passout para ler a senha de outros locais; para
mais detalhes, consulte a
documentação do openssl.
O arquivo intermediário temp.pem contém a chave privada sem qualquer tipo de Por isso, descarte-os com cuidado ao gerar versões chaves. Em particular, o utilitário GNUshred pode não ser eficaz em conexões de rede ou em sistemas de arquivos em diário registrados. Você pode usar um diretório de trabalho localizado em um disco RAM (como uma partição tmpfs) ao gerar chaves para garantir que os intermediários não sejam expostas acidentalmente.
Criar arquivos de imagem
Quando você tiver o signed-target_files.zip
, precisará
para criar a imagem e colocá-la em um dispositivo.
Para criar a imagem assinada usando os arquivos de destino, execute:
use o seguinte comando da raiz do ambiente
árvore:
img_from_target_files signed-target_files.zip signed-img.zipO arquivo resultante,
signed-img.zip
, contém todos os arquivos .img
.
Para carregar uma imagem em um dispositivo, use o fastboot como
da seguinte forma:
fastboot update signed-img.zip