apksigner

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Công cụ apksigner có trong bản sửa đổi 24.0.3 trở lên của Công cụ tạo SDK Android, cho phép bạn ký các tệp APK và xác nhận rằng chữ ký của APK sẽ được xác minh thành công trên tất cả phiên bản của thiết bị Android được các APK đó hỗ trợ. Trang này trình bày hướng dẫn ngắn về cách sử dụng công cụ và đóng vai trò là tài liệu tham khảo cho các tuỳ chọn dòng lệnh khác nhau mà công cụ hỗ trợ. Để xem nội dung mô tả đầy đủ hơn về cách dùng công cụ apksigner để ký tệp APK, vui lòng xem hướng dẫn Ký ứng dụng.

Chú ý: Nếu bạn ký APK bằng apksigner và thực hiện các thay đổi khác đối với APK thì chữ ký của APK này sẽ mất hiệu lực. Do đó, bạn phải sử dụng các công cụ như zipalign trước khi ký APK.

Mức sử dụng

Ký APK

Cú pháp để ký một tệp APK bằng công cụ apksigner như sau:

apksigner sign --ks keystore.jks |
  --key key.pk8 --cert cert.x509.pem
  [signer_options] app-name.apk

Khi ký APK bằng công cụ apksigner, bạn phải cung cấp chứng chỉ và khóa riêng tư của chữ ký. Bạn có thể cung cấp thông tin này bằng hai cách khác nhau:

  • Hãy chỉ định một tệp KeyStore bằng cách sử dụng tùy chọn--ks.
  • Hãy xác định riêng tệp khoá riêng tư và tệp chứng chỉ bằng cách sử dụng lần lượt các tuỳ chọn --key--cert. Tệp khóa riêng tư phải sử dụng định dạng PKCS #8 và tệp chứng chỉ phải sử dụng định dạng X.509.

Thông thường, bạn chỉ ký một APK bằng một chữ ký. Nếu bạn cần ký một APK bằng nhiều chữ ký, hãy dùng tuỳ chọn --next-signer để phân tách nhóm các tuỳ chọn chung để áp dụng cho từng chữ ký:

apksigner sign [signer_1_options] --next-signer [signer_2_options] app-name.apk

Xác minh chữ ký của APK

Cú pháp để xác nhận rằng chữ ký cho một APK sẽ được xác minh thành công trên những nền tảng mà các APK hỗ trợ như sau:

apksigner verify [options] app-name.apk

Xoay vòng mã khóa chữ ký

Cú pháp để xoay loạt chứng chỉ ký nối tiếp hoặc một chuỗi chữ ký mới như sau:

$ apksigner rotate --in /path/to/existing/lineage \
  --out /path/to/new/file \
  --old-signer --ks old-signer-jks \
  --new-signer --ks new-signer-jks

Tùy chọn

Các danh sách sau đây bao gồm tập hợp các tùy chọn cho mỗi lệnh mà công cụ apksigner này hỗ trợ.

Ký lệnh

Tùy chọn chung

Sau đây là một số lựa chọn cài đặt cơ bản áp dụng cho một chữ ký:

--out <apk-filename>
Vị trí bạn muốn lưu APK đã ký. Nếu có lựa chọn rõ ràng thì gói APK sẽ được ký tại chỗ và ghi đè lên tệp APK đầu vào.
--min-sdk-version <integer>
Cấp độ API thấp nhất dành cho khung Android mà apksigner sử dụng để xác nhận rằng chữ ký của APK sẽ được xác minh. Giá trị cao hơn cho phép công cụ sử dụng các tham số có khả năng bảo mật cao hơn khi ký ứng dụng nhưng cũng sẽ hạn chế khả năng hiển thị của APK tới các thiết bị đang chạy thêm các phiên bản hiện tại của Android. Theo mặc định, apksignersử dụng giá trị của minSdkVersion thuộc tính từ tệp kê khai của ứng dụng.
--max-sdk-version <integer>
Cấp độ API thấp nhất dành cho khung Android mà apksigner sử dụng để xác nhận rằng chữ ký của APK sẽ được xác mình. Theo mặc định, công cụ này sử dụng cấp API cao nhất có thể.
--rotation-min-sdk-version <integer>
Cấp API thấp nhất mà khoá ký xoay vòng của APK sẽ dùng để tạo chữ ký của APK. Khoá ký ban đầu (chưa xoay vòng) cho APK sẽ được dùng cho tất cả các phiên bản trước của nền tảng. Theo mặc định, các khoá ký xoay vòng được dùng với khối ký v3.1, được hỗ trợ trên các thiết bị chạy Android 13 (API cấp 33) trở lên.

Lưu ý: Nếu ứng dụng đã được ký bằng khoá ký xoay vòng trên thiết bị chạy Android 12L (API cấp 32) trở xuống, thì bạn phải dùng --rotation-min-sdk-version 28 để tiếp tục ký ứng dụng bằng khoá ký xoay vòng cho Android 9 (API cấp 28).

--v1-signing-enabled <true | false>
Xác định xem apksigner có ký gói APK đã cho bằng giao thức ký truyền thống dựa trên JAR hay không. Theo mặc định, công cụ này sử dụng các giá trị của --min-sdk-version--max-sdk-version để quyết định thời điểm áp dụng lược đồ chữ ký này.
--v2-signing-enabled <true | false>
Xác định xem apksigner có ký gói APK đã cung cấp hay không bằng cách sử dụng Lược đồ chữ ký APK v2. Theo mặc định, công cụ này sử dụng các giá trị của --min-sdk-version--max-sdk-version để quyết định thời điểm áp dụng lược đồ chữ ký này.
--v3-signing-enabled <true | false>
Xác định xem apksigner có ký gói APK đã cung cấp bằng cách sử dụng Lược đồ chữ ký APK v3 hay không. Theo mặc định, công cụ này sử dụng các giá trị của --min-sdk-version--max-sdk-version để quyết định thời điểm áp dụng lược đồ chữ ký này.
--v4-signing-enabled <true | false | only>
Xác định xem apksigner có ký gói APK đã cung cấp hay không bằng cách sử dụng Lược đồ chữ ký APK v4. Lược đồ này tạo ra chữ ký trong một tệp riêng biệt (apk-name.apk.idsig). Nếu true và APK chưa được ký thì chữ ký v2 hoặc v3 sẽ được tạo dựa trên các giá trị của --min-sdk-version--max-sdk-version. Sau đó, lệnh này sẽ tạo tệp .idsig dựa trên nội dung của APK đã ký. Chỉ sử dụng only để tạo chữ ký v4 mà không cần chỉnh sửa APK và mọi chữ ký có trước khi gọi; only sẽ lỗi nếu APK chưa có chữ ký v2 hoặc v3, hoặc nếu chữ ký đã sử dụng khóa khác với khóa đã cung cấp cho lệnh gọi hiện tại. Theo mặc định, công cụ này sử dụng các giá trị của --min-sdk-version--max-sdk-version để quyết định thời điểm áp dụng lược đồ chữ ký này.
-v, --verbose
Sử dụng chế độ dữ liệu đầu ra chi tiết.

Tùy chọn đối với mỗi chữ ký

Các tuỳ chọn sau đây xác định cấu hình cho một chữ ký cụ thể. Các tuỳ chọn này không cần thiết nếu bạn chỉ ký ứng dụng bằng một chữ ký duy nhất.

--next-signer <signer-options>
Dùng để xác định các tùy chọn chung cho từng chữ ký.
--v1-signer-name <basename>
Tên gốc cho các tệp bao gồm chữ ký dựa trên JAR dành cho chữ ký hiện tại. Theo mặc định, apksigner sử dụng bí dah khoá cho kho khoá hoặc basename của tệp khoá cho chữ ký này.

Tùy chọn đối với khóa và chứng chỉ

Các tuỳ chọn sau đây xác định khoá riêng tư và chứng chỉ của chữ ký:

--ks <filename>
Khóa riêng tư và chuỗi chứng chỉ của chữ ký có trong tệp kho khoá dựa trên Java đã cung cấp. Nếu tên tệp được đặt thành "NONE" thì kho khoá chứa khóa và chứng chỉ sẽ không cần tệp được chỉ định, tệp này chỉ cần thiết trong trường hợp của một số kho khoá PKCS #11.
--ks-key-alias <alias>
Tên của bí danh đại diện cho dữ liệu khóa riêng tư và chứng chỉ của chữ ký trong KeyStore. Nếu Kho khoá liên kết với ký hiệu có chứa nhiều khóa thì bạn phải xác định rõ tùy chọn này.
--ks-pass <input-format>

Mật khẩu cho KeyStore chứa khóa riêng tư và chứng chỉ của chữ ký. Bạn phải cung cấp mật khẩu để mở kho khoá. Công cụ apksigner hỗ trợ các định dạng sau:

  • pass:<password> – Mật khẩu được cung cấp khớp với phần còn lại của lệnh apksigner sign.
  • env:<name> – Mật khẩu được lưu trữ dưới dạng biến môi trường được cung cấp.
  • file:<filename> – Mật khẩu được lưu trữ dưới dạng một dòng trong tệp được cung cấp.
  • stdin – Mật khẩu được cung cấp dưới dạng một dòng trong luồng dữ liệu nhập tiêu chuẩn. Đây là hành vi mặc định cho --ks-pass.

Lưu ý: Nếu bạn đặt nhiều mật khẩu trong cùng một tệp, hãy đặt các mật khẩu đó tại các dòng riêng biệt. Công cụ apksigner liên kết mật khẩu với các chữ ký APK dựa trên thứ tự mà bạn chỉ định cho từng chữ ký. Nếu bạn đã cung cấp hai mật khẩu cho chữ ký thì apksigner sẽ hiểu mật khẩu đầu tiên là mật khẩu kho khoá và mật khẩu thứ hai là mật khẩu khóa.

--pass-encoding <charset>
Bao gồm chế độ mã hoá ký tự được chỉ định (chẳng hạn như ibm437 hoặc utf-8) khi cố gắng xử lý các mật khẩu có chứa ký tự không phải là ASCII.

Keytool thường mã hóa các kho khóa bằng cách chuyển đổi mật khẩu bằng bộ ký tự mặc định của bảng điều khiển. Theo mặc định, apksigner giải mã thông qua một vài dạng mật khẩu: mẫu Unicode, mẫu được mã hóa bằng bộ ký tự JVM mặc định và đối với Java từ 8 trở xuống, biểu mẫu được mã hóa bằng bộ ký tự mặc định. Với Java 9, apksigner không thể phát hiện bộ ký tự của bảng điều khiển. Vì vậy, bạn có thể cần chỉ định --pass-encoding khi sử dụng mật khẩu không phải ASCII. Bạn cũng có thể cần xác định tùy chọn này bằng các kho khóa mà keytool được tạo trên một hệ điều hành khác hoặc ở một ngôn ngữ khác.

--key-pass <input-format>

Mật khẩu cho khóa riêng tư của chữ ký - yếu tố cần thiết trong trường hợp khóa riêng tư được bảo vệ bằng mật khẩu. Công cụ apksigner hỗ trợ các định dạng sau:

  • pass:<password> – Mật khẩu được cung cấp khớp với phần còn lại của lệnh apksigner sign.
  • env:<name> – Mật khẩu được lưu trữ dưới dạng biến môi trường được cung cấp.
  • file:<filename> – Mật khẩu được lưu trữ dưới dạng một dòng trong tệp được cung cấp.
  • stdin – Mật khẩu được cung cấp dưới dạng một dòng trong luồng dữ liệu nhập tiêu chuẩn. Đây là hành vi mặc định cho --key-pass.

Lưu ý: Nếu bạn đặt nhiều mật khẩu trong cùng một tệp, hãy đặt các mật khẩu đó tại các dòng riêng biệt. Công cụ apksigner liên kết mật khẩu với các chữ ký APK dựa trên thứ tự mà bạn chỉ định cho từng chữ ký. Nếu bạn đã cung cấp hai mật khẩu cho chữ ký thì apksigner sẽ hiểu mật khẩu đầu tiên là mật khẩu kho khoá và mật khẩu thứ hai là mật khẩu khóa.

--ks-type <algorithm>
Loại hoặc thuật toán liên kết với kho khoá có chứa khóa và riêng tư chứng chỉ của chữ ký. Theo mặc định, apksigner sử dụng loại được xác định là hằng số keystore.type trong tệp thuộc tính bảo mật.
--ks-provider-name <name>
Tên của Nhà cung cấp JCA để sử dụng khi yêu cầu triển khai KeyStore của chữ ký. Theo mặc định, apksigner sử dụng nhà cung cấp có mức độ ưu tiên cao nhất.
--ks-provider-class <class-name>
Tên lớp đủ điều kiện của Nhà cung cấp JCA để sử dụng khi yêu cầu triển khai kho khoá của chữ ký. Tùy chọn này thay thế cho --ks-provider-name. Theo mặc định, apksigner sử dụng nhà cung cấp được chỉ định với tùy chọn --ks-provider-name.
--ks-provider-arg <value>
Một giá trị chuỗi cần chuyển vào làm đối số cho hàm dựng của lớp Nhà cung cấp JCA; bản thân lớp này được xác định thông qua tùy chọn --ks-provider-class. Theo mặc định, apksignersử dụng hàm dựng đối số 0 của lớp này.
--key <filename>
Tên tệp có chứa khóa riêng tư của chữ ký. Tệp này phải sử dụng định dạng DER PKCS #8. Trường hợp khóa được bảo vệ bằng mật khẩu thì apksigner sẽ yêu cầu mật khẩu bằng cách sử dụng phương thức nhập tiêu chuẩn, trừ trường hợp bạn chỉ định một loại định dạng nhập khác bằng tùy chọn --key-pass.
--cert <filename>
Tên của tệp chứa chuỗi chứng chỉ của chữ ký. Tệp này phải sử dụng định dạng X.509 PEM hoặc DER.

Xác minh lệnh

--print-certs
Hiển thị thông tin về chứng chỉ ký của APK.
--min-sdk-version <integer>
Cấp độ API thấp nhất dành cho khung Android mà apksigner sử dụng để xác nhận rằng chữ ký của APK sẽ được xác minh. Giá trị cao hơn cho phép công cụ sử dụng các tham số có khả năng bảo mật cao hơn khi ký ứng dụng nhưng cũng sẽ hạn chế khả năng hiển thị của APK tới các thiết bị đang chạy thêm các phiên bản hiện tại của Android. Theo mặc định, apksignersử dụng giá trị của minSdkVersion thuộc tính từ tệp kê khai của ứng dụng.
--max-sdk-version <integer>
Cấp độ API thấp nhất dành cho khung Android mà apksigner sử dụng để xác nhận rằng chữ ký của APK sẽ được xác mình. Theo mặc định, công cụ này sử dụng cấp API cao nhất có thể.
-v, --verbose
Sử dụng chế độ dữ liệu đầu ra chi tiết.
-Werr
Cảnh báo lỗi.

Ví dụ

Ký APK

Ký APK bằng cách sử dụng release.jks. Đây là khóa duy nhất trong kho khoá:

$ apksigner sign --ks release.jks app.apk

Ký APK bằng cách sử dụng một khóa riêng tư và chứng chỉ, được lưu trữ dưới dạng tệp riêng biệt:

$ apksigner sign --key release.pk8 --cert release.x509.pem app.apk

Ký APK bằng 2 khoá:

$ apksigner sign --ks first-release-key.jks --next-signer --ks second-release-key.jks app.apk

Ký APK bằng khoá ký xoay vòng và SDK nhắm mục tiêu xoay vòng phiên bản 28 trở lên:

$ apksigner sign --ks release.jks --next-signer --ks release2.jks \
  --lineage /path/to/signing/history/lineage app.apk \
  --rotation-min-sdk-version 28

Ký APK bằng khoá ký xoay vòng và SDK nhắm mục tiêu xoay vòng phiên bản 33 trở lên:

$ apksigner sign --ks release.jks --next-signer --ks release2.jks \
  --lineage /path/to/signing/history/lineage app.apk

Xác minh chữ ký của APK

Kiểm tra xem chữ ký của APK dự kiến được xác nhận có hợp lệ trên tất cả các nền tảng Android mà APK đó hỗ trợ hay không:

$ apksigner verify app.apk

Kiểm tra xem chữ ký của APK dự kiến sẽ được xác nhận có hợp lệ trên Android 4.0.3 (API cấp 15) trở lên hay không:

$ apksigner verify --min-sdk-version 15 app.apk

Xoay vòng mã khóa chữ ký

Bật loạt chứng chỉ ký nối tiếp hỗ trợ xoay vòng khóa:

$ apksigner rotate --out /path/to/new/file --old-signer \
    --ks release.jks --new-signer --ks release2.jks

Xoay lại các khóa ký:

$ apksigner rotate --in /path/to/existing/lineage \
  --out /path/to/new/file --old-signer --ks release2.jks \
  --new-signer --ks release3.jks