Đăng bản dựng để phát hành

Hình ảnh hệ điều hành Android sử dụng chữ ký mật mã ở hai nơi:

  1. Mỗi tệp .apk bên trong hình ảnh phải được ký. Trình quản lý gói của Android sử dụng chữ ký .apk theo hai cách:
    • Khi một ứng dụng được thay thế, nó phải được ký bằng cùng khóa với ứng dụng cũ để có quyền truy cập vào dữ liệu của ứng dụng cũ. Điều này đúng cho cả việc cập nhật ứng dụng của người dùng bằng cách ghi .apk và ghi đè ứng dụng hệ thống bằng phiên bản mới hơn được cài đặt bên dưới /data .
    • Nếu hai hoặc nhiều ứng dụng muốn chia sẻ ID người dùng (để chúng có thể chia sẻ dữ liệu, v.v.) thì chúng phải được ký bằng cùng một khóa.
  2. Các gói cập nhật OTA phải được ký bằng một trong các khóa mà hệ thống mong đợi nếu không quá trình cài đặt sẽ từ chối chúng.

Phím nhả

Cây Android bao gồm các khóa kiểm tra trong build/target/product/security . Xây dựng hình ảnh hệ điều hành Android bằng cách sử dụng make sẽ ký tất cả các tệp .apk bằng phím kiểm tra. Vì các khóa kiểm tra được biết đến công khai nên bất kỳ ai cũng có thể ký các tệp .apk của riêng họ bằng các khóa tương tự, điều này có thể cho phép họ thay thế hoặc chiếm quyền điều khiển các ứng dụng hệ thống được tích hợp trong hình ảnh hệ điều hành của bạn. Vì lý do này, điều quan trọng là phải ký bất kỳ hình ảnh hệ điều hành Android nào được phát hành hoặc triển khai công khai bằng một bộ khóa phát hành đặc biệt mà chỉ bạn mới có quyền truy cập.

Để tạo bộ khóa phát hành duy nhất của riêng bạn, hãy chạy các lệnh này từ thư mục gốc của cây 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 phải được thay đổi để phản ánh thông tin về tổ chức của bạn. Bạn có thể sử dụng bất kỳ thư mục nào nhưng hãy cẩn thận chọn vị trí được sao lưu và bảo mật. Một số nhà cung cấp chọn mã hóa khóa riêng của họ bằng cụm mật khẩu mạnh và lưu trữ khóa được mã hóa trong kiểm soát nguồn; những người khác lưu trữ khóa phát hành của họ ở một nơi hoàn toàn khác, chẳng hạn như trên máy tính có air-gap.

Để tạo hình ảnh phát hành, hãy sử dụng:

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

Tập lệnh sign_target_files_apks lấy tệp đích .zip làm đầu vào và tạo ra tệp đích .zip mới trong đó tất cả các tệp .apk đã được ký bằng khóa mới. Bạn có thể tìm thấy những hình ảnh mới được ký bên dưới IMAGES/ trong signed-target_files.zip .

Ký gói OTA

Có thể chuyển đổi tệp zip đích đã ký thành tệp zip cập nhật OTA đã ký bằng quy trình sau:
ota_from_target_files \
-k  (--package_key) 
signed-target_files.zip \
signed-ota_update.zip

Chữ ký và tải bên

Sideloading không bỏ qua cơ chế xác minh chữ ký gói thông thường của recovery—trước khi cài đặt một gói, recovery sẽ xác minh rằng gói đó được ký bằng một trong các khóa riêng khớp với khóa chung được lưu trữ trong phân vùng khôi phục, giống như đối với gói được phân phối qua mạng. -không khí.

Các gói cập nhật nhận được từ hệ thống chính thường được xác minh hai lần: một lần bởi hệ thống chính, sử dụng phương thức RecoverySystem.verifyPackage() trong API Android và sau đó một lần nữa bằng khôi phục. API RecoverySystem kiểm tra chữ ký đối với các khóa chung được lưu trữ trong hệ thống chính, trong tệp /system/etc/security/otacerts.zip (theo mặc định). Recovery kiểm tra chữ ký đối với các khóa chung được lưu trong đĩa RAM phân vùng khôi phục, trong tệp /res/keys .

Theo mặc định, tệp đích .zip do bản dựng tạo sẽ đặt chứng chỉ OTA khớp với khóa kiểm tra. Trên hình ảnh được phát hành, phải sử dụng chứng chỉ khác để thiết bị có thể xác minh tính xác thực của gói cập nhật. Chuyển cờ -o tới sign_target_files_apks , như được hiển thị trong phần trước, sẽ thay thế chứng chỉ khóa kiểm tra bằng chứng chỉ khóa phát hành từ thư mục certs của bạn.

Thông thường, hình ảnh hệ thống và hình ảnh khôi phục lưu trữ cùng một bộ khóa công khai OTA. Bằng cách thêm khóa vào bộ khóa khôi phục, có thể ký các gói chỉ có thể được cài đặt thông qua sideloading (giả sử cơ chế tải xuống bản cập nhật của hệ thống chính đang thực hiện xác minh chính xác đối với otacerts.zip). Bạn có thể chỉ định các khóa bổ sung chỉ được đưa vào quá trình khôi phục bằng cách đặt biến product_EXTRA_RECOVERY_KEYS trong định nghĩa sản phẩm của mình:

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

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

Điều này bao gồm vendor/yoyodyne/security/tardis/sideload.x509.pem trong tệp khóa khôi phục để nó có thể cài đặt các gói được ký với nó. Tuy nhiên, khóa bổ sung không được bao gồm trong otacerts.zip, vì vậy các hệ thống xác minh chính xác các gói đã tải xuống sẽ không gọi quá trình khôi phục cho các gói được ký bằng khóa này.

Chứng chỉ và khóa riêng

Mỗi khóa có hai tệp: chứng chỉ , có phần mở rộng .x509.pem và khóa riêng tư , có phần mở rộng .pk8. Khóa riêng phải được giữ bí mật và cần thiết để ký một gói hàng. Bản thân khóa có thể được bảo vệ bằng mật khẩu. Ngược lại, chứng chỉ chỉ chứa một nửa khóa công khai nên có thể được phân phối rộng rãi. Nó được sử dụng để xác minh một gói đã được ký bằng khóa riêng tương ứng.

Bản dựng Android tiêu chuẩn sử dụng năm khóa, tất cả đều nằm trong build/target/product/security :

khóa kiểm tra
Khóa mặc định chung cho các gói không chỉ định khóa khác.
nền tảng
Khóa kiểm tra các gói là một phần của nền tảng cốt lõi.
đã chia sẻ
Khóa kiểm tra những nội dung được chia sẻ trong quy trình nhà riêng/danh bạ.
phương tiện truyền thông
Khóa kiểm tra các gói là một phần của hệ thống tải xuống/phương tiện truyền thông.
ngăn xếp mạng
Khóa kiểm tra các gói là một phần của hệ thống mạng. Khóa networkstack được sử dụng để ký các tệp nhị phân được thiết kế dưới dạng Thành phần hệ thống mô-đun . Nếu các bản cập nhật mô-đun của bạn được xây dựng riêng biệt và được tích hợp dưới dạng bản dựng sẵn trong hình ảnh thiết bị của bạn thì bạn có thể không cần tạo khóa networkstack trong cây nguồn Android.

Các gói riêng lẻ chỉ định một trong các khóa này bằng cách đặt LOCAL_CERTIFICATE trong tệp Android.mk của chúng. (khóa kiểm tra được sử dụng nếu biến này không được đặt.) Bạn cũng có thể chỉ định một khóa hoàn toàn khác theo tên đường dẫn, ví dụ:

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

LOCAL_CERTIFICATE := device/yoyodyne/security/special

Bây giờ bản dựng sử dụng khóa device/yoyodyne/security/special.{x509.pem,pk8} để ký SpecialApp.apk. Bản dựng chỉ có thể sử dụng các khóa riêng không được bảo vệ bằng mật khẩu.

Tùy chọn ký nâng cao

Thay thế khóa ký APK

Tập lệnh ký sign_target_files_apks hoạt động trên các tệp mục tiêu được tạo cho bản dựng. Tất cả thông tin về chứng chỉ và khóa riêng được sử dụng tại thời điểm xây dựng đều được bao gồm trong tệp đích. Khi chạy tập lệnh ký để ký phát hành, khóa ký có thể được thay thế dựa trên tên khóa hoặc tên APK.

Sử dụng cờ --key_mapping--default_key_mappings để chỉ định thay thế khóa dựa trên tên khóa:

  • Cờ --key_mapping src_key = dest_key chỉ định việc thay thế một khóa tại một thời điểm.
  • Cờ --default_key_mappings dir chỉ định một thư mục có năm khóa để thay thế tất cả các khóa trong build/target/product/security ; việc này tương đương với việc sử dụng --key_mapping năm lần để chỉ định ánh xạ.
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

Sử dụng cờ --extra_apks apk_name1,apk_name2,... = key để chỉ định các thay thế khóa ký dựa trên tên APK. Nếu key bị bỏ trống, tập lệnh sẽ coi các APK được chỉ định là đã được ký trước.

Đối với sản phẩm tardis giả định, bạn cần sáu khóa được bảo vệ bằng mật khẩu: năm khóa để thay thế năm khóa trong build/target/product/security và một khóa để thay thế khóa bổ sung device/yoyodyne/security/special mà SpecialApp yêu cầu trong ví dụ trên. Nếu các khóa nằm trong các tệp sau:

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

Sau đó, bạn sẽ ký tất cả các ứng dụng như thế này:

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

Điều này mang lại những điều sau đây:

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.

Sau khi nhắc người dùng nhập mật khẩu cho tất cả các khóa được bảo vệ bằng mật khẩu, tập lệnh sẽ ký lại tất cả các tệp APK trong mục tiêu đầu vào .zip bằng các khóa phát hành. Trước khi chạy lệnh, bạn cũng có thể đặt biến môi trường ANDROID_PW_FILE thành tên tệp tạm thời; sau đó tập lệnh sẽ gọi trình soạn thảo của bạn để cho phép bạn nhập mật khẩu cho tất cả các khóa (đây có thể là cách thuận tiện hơn để nhập mật khẩu).

Thay thế khóa ký APEX

Android 10 giới thiệu định dạng tệp APEX để cài đặt các mô-đun hệ thống cấp thấp hơn. Như đã giải thích trong phần ký APEX , mỗi tệp APEX được ký bằng hai khóa: một cho hình ảnh hệ thống tệp nhỏ trong APEX và khóa kia cho toàn bộ APEX.

Khi ký phát hành, hai khóa ký cho tệp APEX được thay thế bằng khóa phát hành. Khóa tải trọng hệ thống tệp được chỉ định bằng cờ --extra_apex_payload và toàn bộ khóa ký tệp APEX được chỉ định bằng cờ --extra_apks .

Đối với sản phẩm tardis, giả sử rằng bạn có cấu hình khóa sau cho các tệp com.android.conscrypt.apex , com.android.media.apexcom.android.runtime.release.apex 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"

Và bạn có các tệp sau chứa các khóa phát hành:

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

Lệnh sau sẽ ghi đè các khóa ký cho com.android.runtime.release.apexcom.android.tzdata.apex trong quá trình ký phát hành. Cụ thể, com.android.runtime.release.apex được ký bằng các khóa phát hành được chỉ định ( runtime_apex_container cho tệp APEX và runtime_apex_payload cho tải trọng hình ảnh tệp). com.android.tzdata.apex được coi là đã ký trước. Tất cả các tệp APEX khác được xử lý theo cấu hình mặc định như được liệt kê trong tệp đích.

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

Chạy lệnh trên sẽ đưa ra các nhật ký sau:

        [...]
    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)
        [...]

Sự lựa chọn khác

Tập lệnh ký sign_target_files_apks viết lại mô tả bản dựng và dấu vân tay trong các tệp thuộc tính bản dựng để phản ánh rằng bản dựng là bản dựng đã ký. Cờ --tag_changes kiểm soát những chỉnh sửa nào được thực hiện đối với dấu vân tay. Chạy tập lệnh với -h để xem tài liệu về tất cả các cờ.

Tạo khóa thủ công

Android sử dụng khóa RSA 2048 bit với số mũ công khai 3. Bạn có thể tạo cặp chứng chỉ/khóa riêng bằng công cụ openssl từ 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

Lệnh openssl pkcs8 nêu trên tạo tệp .pk8 không có mật khẩu, phù hợp để sử dụng với hệ thống xây dựng. Để tạo .pk8 được bảo mật bằng mật khẩu (điều bạn nên làm đối với tất cả các khóa phát hành thực tế), hãy thay thế đối số -nocrypt bằng -passout stdin ; sau đó openssl sẽ mã hóa khóa riêng bằng mật khẩu được đọc từ đầu vào tiêu chuẩn. Không có lời nhắc nào được in ra, vì vậy nếu stdin là thiết bị đầu cuối, chương trình sẽ bị treo khi nó thực sự chỉ chờ bạn nhập mật khẩu. Các giá trị khác có thể được sử dụng cho đối số-passout để đọc mật khẩu từ các vị trí khác; để biết chi tiết, xem tài liệu openssl .

Tệp trung gian temp.pem chứa khóa riêng mà không có bất kỳ loại bảo vệ mật khẩu nào, vì vậy hãy loại bỏ nó một cách cẩn thận khi tạo khóa phát hành. Đặc biệt, tiện ích GNUshred có thể không hiệu quả trên mạng hoặc hệ thống tệp được ghi nhật ký. Bạn có thể sử dụng thư mục làm việc nằm trong đĩa RAM (chẳng hạn như phân vùng tmpfs) khi tạo khóa để đảm bảo các khóa trung gian không vô tình bị lộ.

Tạo tập tin hình ảnh

Khi bạn đã có signed-target_files.zip , bạn cần tạo hình ảnh để có thể đưa nó vào thiết bị. Để tạo hình ảnh đã ký từ các tệp mục tiêu, hãy chạy lệnh sau từ thư mục gốc của cây Android:

img_from_target_files signed-target_files.zip signed-img.zip
Tệp kết quả, signed-img.zip , chứa tất cả các tệp .img . Để tải hình ảnh vào thiết bị, hãy sử dụng fastboot như sau:
fastboot update signed-img.zip