apksigner

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 khóa riêng tư và tệp chứng chỉ bằng cách sử dụng các tùy 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 sử dụng tùy chọn --next-signer để phân tách nhóm các tùy 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ý cho 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. Công cụ này sử dụng cấp API cao nhất có thể theo mặc định.
--v1-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 giao thức ký dựa trên JAR truyền thố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 các tùy chọn mã hóa ký tự được chỉ định (chẳng hạn như ibm437 hoặc utf-8) khi xử lý các mật khẩu có chứa ký tự không phải 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. Công cụ này sử dụng cấp API cao nhất có thể theo mặc định.
-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 hai khóa:

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

Xác minh chữ ký cho 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