Google se compromete a impulsar la igualdad racial para las comunidades afrodescendientes. Obtén información al respecto.

Firma de compilaciones para su lanzamiento

Las imágenes del sistema operativo Android utilizan firmas criptográficas en dos lugares:

  1. Cada .apk archivo dentro de la imagen debe ser firmado. Android de Administrador de paquetes utiliza un .apk la firma de dos maneras:
    • Cuando se reemplaza una aplicación, debe estar firmada con la misma clave que la aplicación anterior para poder acceder a los datos de la aplicación anterior. Esto es válido tanto para la actualización de aplicaciones de usuario sobrescribiendo el .apk , y para anular una aplicación del sistema con una versión más reciente instalado bajo /data .
    • Si dos o más aplicaciones desean compartir una identificación de usuario (para que puedan compartir datos, etc.), deben estar firmadas con la misma clave.
  2. Los paquetes de actualización OTA deben estar firmados con una de las claves esperadas por el sistema o el proceso de instalación los rechazará.

Liberar llaves

El árbol Android incluye claves de prueba en virtud de build/target/product/security . La construcción de una imagen usando el sistema operativo Android make firmará todos .apk archivos usando las teclas de prueba. Dado que las claves de prueba se conocen públicamente, cualquiera puede firmar sus propios archivos .apk con las mismas claves, lo que puede permitirles reemplazar o secuestrar aplicaciones del sistema integradas en la imagen de su sistema operativo. Por esta razón, es fundamental para firmar cualquier imagen Android OS liberado o desplegados públicamente con un conjunto especial de teclas de liberación que sólo usted tiene acceso.

Para generar su propio conjunto único de claves de lanzamiento, ejecute estos comandos desde la raíz de su árbol de 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

$subject debe ser cambiado para reflejar la información de su organización. Puede usar cualquier directorio, pero tenga cuidado de elegir una ubicación que esté respaldada y sea segura. Algunos proveedores optan por cifrar su clave privada con una contraseña segura y almacenar la clave cifrada en el control de fuente; otros almacenan sus claves de liberación en otro lugar completamente diferente, como en una computadora con espacio de aire.

Para generar una imagen de lanzamiento, 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

El sign_target_files_apks script toma un objetivo a archivos .zip como entrada y produce un nuevo objetivo archivos .zip en el que todos los .apk archivos se han firmado con nuevas claves. Las imágenes de nueva firma se pueden encontrar en IMAGES/ en signed-target_files.zip .

Firma de paquetes OTA

Una meta de archivos zip firmados se pueden convertir en una cremallera actualización OTA firmado con el siguiente procedimiento:
ota_from_target_files \
-k  (--package_key) 
signed-target_files.zip \
signed-ota_update.zip

Firmas y descarga lateral

La carga lateral no omite el mecanismo normal de verificación de firmas de paquetes de recuperación; antes de instalar un paquete, la recuperación verificará que esté firmado con una de las claves privadas que coincida con las claves públicas almacenadas en la partición de recuperación, tal como lo haría con un paquete entregado a través de la -aire.

Los paquetes de actualización recibido desde el sistema principal típicamente se verificaron dos veces: una vez por el sistema principal, utilizando el RecoverySystem.verifyPackage() método en el API androide, y luego otra vez por la recuperación. Los cheques API RecoverySystem la firma contra claves públicas almacenadas en el sistema principal, en el archivo /system/etc/security/otacerts.zip (por defecto). Cheques de recuperación de la firma contra claves públicas almacenadas en el disco RAM partición de recuperación, en el archivo /res/keys .

De manera predeterminada, los archivos de destino .zip producidos por los conjuntos de construir el certificado de OTA para que coincida con la clave de prueba. En una imagen publicada, se debe utilizar un certificado diferente para que los dispositivos puedan verificar la autenticidad del paquete de actualización. Pasando el -o bandera para sign_target_files_apks , como se muestra en la sección anterior, sustituye el certificado de clave de prueba con el certificado de clave de liberación de su directorio certs.

Normalmente, la imagen del sistema y la imagen de recuperación almacenan el mismo conjunto de claves públicas OTA. Mediante la adición de una clave a poco el conjunto de recuperación de claves, es posible firmar los paquetes que sólo se puede instalar a través de carga lateral (suponiendo mecanismo de descarga de la actualización del sistema principal está haciendo correctamente la verificación respecto a otacerts.zip). Puede especificar claves adicionales para que se incluyan solo en la recuperación configurando la variable PRODUCT_EXTRA_RECOVERY_KEYS en la definición de su producto:

vendor/yoyodyne/tardis/products/tardis.mk
 [...]

PRODUCT_EXTRA_RECOVERY_KEYS := vendor/yoyodyne/security/tardis/sideload

Esto incluye la clave pública vendor/yoyodyne/security/tardis/sideload.x509.pem en el archivo de claves de recuperación para que pueda instalar paquetes firmados con ella. La llave extra no está incluido en otacerts.zip embargo, lo que los sistemas que verifican correctamente los paquetes descargados no lo hacen invocación de recuperación de paquetes firmados con esta clave.

Certificados y claves privadas

Cada llave viene en dos archivos: el certificado, que tiene la .x509.pem extensión, y la clave privada, que tiene la .pk8 extensión. La clave privada debe mantenerse en secreto y es necesaria para firmar un paquete. La clave en sí misma puede estar protegida por una contraseña. El certificado, por el contrario, contiene solo la mitad pública de la clave, por lo que puede distribuirse ampliamente. Se utiliza para verificar que un paquete haya sido firmado por la clave privada correspondiente.

La norma de construcción Android utiliza cinco teclas, todos los cuales residen en build/target/product/security :

clave de prueba
Clave genérica predeterminada para paquetes que no especifican una clave de otra manera.
plataforma
Clave de prueba para paquetes que forman parte de la plataforma principal.
compartido
Prueba la clave para las cosas que se comparten en el proceso de inicio / contactos.
medios de comunicación
Clave de prueba para paquetes que forman parte del sistema de medios / descarga.
pila de red
Clave de prueba para paquetes que forman parte del sistema de red. La clave networkstack se utiliza para firmar los binarios diseñados como modular los componentes del sistema . Si las actualizaciones de su módulo se crean por separado y se integran como precompilaciones en la imagen de su dispositivo, es posible que no necesite generar una clave de pila de red en el árbol de fuentes de Android.

Los paquetes individuales especifican una de estas claves configurando LOCAL_CERTIFICATE en su archivo Android.mk. (testkey se usa si esta variable no está configurada). También puede especificar una clave completamente diferente por nombre de ruta, por ejemplo:

device/yoyodyne/apps/SpecialApp/Android.mk
 [...]

LOCAL_CERTIFICATE := device/yoyodyne/security/special

Ahora la acumulación utiliza el device/yoyodyne/security/special.{x509.pem,pk8} clave para firmar SpecialApp.apk. La acumulación sólo puede utilizar las claves privadas que no están protegidos por contraseña.

Opciones de firma avanzadas

Reemplazo de clave de firma de APK

Las secuencias de comandos firma sign_target_files_apks trabaja en los archivos de destino generados por una acumulación. Toda la información sobre certificados y claves privadas utilizadas en el momento de la compilación se incluye en los archivos de destino. Cuando se ejecuta el script de firma para firmar la liberación, las claves de firma se pueden reemplazar según el nombre de la clave o el nombre del APK.

Utilice los --key_mapping y --default_key_mappings banderas para especificar sustitución de claves basado en nombres clave:

  • El --key_mapping src_key = dest_key bandera especifica el reemplazo de una tecla a la vez.
  • El --default_key_mappings dir bandera especifica un directorio con cinco teclas para reemplazar todas las claves en build/target/product/security ; que es equivalente a usar --key_mapping cinco veces para especificar las asignaciones.
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

Usar la --extra_apks apk_name1,apk_name2,... = key bandera para especificar los reemplazos de la clave de firma en base a los nombres de APK. Si key se deja vacío, las golosinas de guión aPKs los especificados como pre-firmado.

Para el producto Tardis hipotética, necesita seis claves protegidas por contraseña: cinco para sustituir a los cinco en build/target/product/security , y uno para reemplazar la clave adicional device/yoyodyne/security/special requerida por SpecialApp en el ejemplo anterior. Si las claves estuvieran en los siguientes archivos:

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

Entonces firmarías todas las aplicaciones así:

./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

Esto trae a colación lo siguiente:

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.

Después de preguntar al usuario para contraseñas para todas las claves protegidas por contraseña, el script vuelve a firmar todos los archivos APK en el objetivo de entrada .zip con las llaves de liberación. Antes de ejecutar el comando, también puede configurar el ANDROID_PW_FILE variable de entorno a un nombre de archivo temporal; el script luego invoca a su editor para permitirle ingresar contraseñas para todas las claves (esta puede ser una forma más conveniente de ingresar contraseñas).

Reemplazo de clave de firma APEX

Android 10 introduce el formato de archivo APEX para la instalación de los módulos del sistema de nivel inferior. Como se explica en APEX firma , cada archivo APEX está firmado con dos claves: una imagen de mini sistema de archivos dentro de un APEX y el otro para toda la APEX.

Al firmar para la liberación, las dos claves de firma para un archivo APEX se reemplazan con claves de liberación. La clave de la carga útil del sistema de archivos se especifica con el --extra_apex_payload bandera y todo el archivo de claves de firma APEX se especifica con el --extra_apks bandera.

Para el producto Tardis, se supone que tiene la siguiente configuración clave para el com.android.conscrypt.apex , com.android.media.apex y com.android.runtime.release.apex archivos 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"

Y tiene los siguientes archivos que contienen las claves de lanzamiento:

vendor/yoyodyne/security/runtime_apex_container.x509.pem
vendor/yoyodyne/security/runtime_apex_container.pk8
vendor/yoyodyne/security/runtime_apex_payload.pem

El siguiente comando anula las claves de firma para com.android.runtime.release.apex y com.android.tzdata.apex durante la liberación de firma. En particular, com.android.runtime.release.apex está firmado con las llaves de liberación especificado ( runtime_apex_container para el archivo de APEX, y runtime_apex_payload para la imagen de carga de archivos). com.android.tzdata.apex se trata como pre-firmado. Todos los demás archivos APEX se manejan con la configuración predeterminada que se enumera en los archivos 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

Al ejecutar el comando anterior, se obtienen los siguientes 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)
        [...]

Otras opciones

Los sign_target_files_apks firma reescrituras de guión la descripción de la compilación y la huella digital en los archivos de propiedades de construcción para reflejar que la construcción es una construcción firmado. El --tag_changes controles bandera lo ediciones se realizan para la huella dactilar. Ejecutar el script con -h para ver la documentación de todas las banderas.

Generación manual de claves

Usos Android claves RSA de 2048 bits con exponente público 3. Puede generar el certificado / pares de clave privada usando la herramienta openssl de openssl.org :

# generate RSA key
openssl 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 key
openssl 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 key
openssl pkcs8 -in temp.pem -topk8 -outform DER -out releasekey.pk8 -nocrypt

# securely delete the temp.pem file
shred --remove temp.pem

El comando openssl PKCS8 dado anteriormente crea un archivo .pk8 sin contraseña, adecuado para su uso con el sistema de construcción. Para crear un .pk8 asegurado con una contraseña (que usted debe hacer para todas las llaves de liberación reales), reemplace el -nocrypt discusión con -passout stdin ; luego openssl cifrará la clave privada con una contraseña leída de la entrada estándar. No se imprime ningún mensaje, por lo que si stdin es el terminal, el programa parecerá colgarse cuando en realidad solo está esperando que ingrese una contraseña. Se pueden usar otros valores para el argumento-passout para leer la contraseña desde otras ubicaciones; para más detalles, consulte la documentación de OpenSSL .

El archivo intermedio temp.pem contiene la clave privada sin ningún tipo de protección por contraseña, así que deséchelo cuidadosamente cuando genere claves de liberación. En particular, la utilidad GNUshred puede no ser eficaz en sistemas de archivos de red o registrados. Puede usar un directorio de trabajo ubicado en un disco RAM (como una partición tmpfs) al generar claves para asegurarse de que los intermedios no se expongan inadvertidamente.

Creando archivos de imagen

Una vez que haya firmado-target-files.zip, debe crear la imagen para poder colocarla en un dispositivo. Para crear la imagen firmada a partir de los archivos de destino, ejecute el siguiente comando desde la raíz del árbol de Android:

img_from_target_files signed-target-files.zip signed-img.zip
El archivo resultante, signed-img.zip , contiene todos los archivos .img. Para cargar una imagen en un dispositivo, el uso fastboot como sigue:
fastboot update signed-img.zip