apksigner

เครื่องมือ apksigner ซึ่งมีให้ใช้งานในเครื่องมือสร้าง Android SDK ตั้งแต่เวอร์ชันแก้ไข 24.0.3 ขึ้นไป ช่วยให้คุณลงนามใน APK และยืนยันว่าลายเซ็นของ APK จะผ่านการยืนยันในแพลตฟอร์ม Android ทุกเวอร์ชันที่ APK นั้นรองรับ

หน้านี้จะแสดงคำแนะนำสั้นๆ เกี่ยวกับการใช้เครื่องมือและเป็นข้อมูลอ้างอิงสำหรับตัวเลือกบรรทัดคำสั่งต่างๆ ที่เครื่องมือรองรับ ดูคำอธิบายที่สมบูรณ์เพิ่มเติมเกี่ยวกับวิธีใช้เครื่องมือ apksigner ในการลงชื่อ APK ได้ที่ลงชื่อแอป

ข้อควรระวัง: หากคุณรับรอง APK โดยใช้ apksigner และทำการเปลี่ยนแปลงเพิ่มเติมใน APK ระบบจะถือว่าลายเซ็นของ APK ไม่ถูกต้อง หากคุณใช้ zipalign เพื่อจัดเรียง APK ให้ใช้ก่อนที่จะรับรอง APK

การใช้งาน

ลงชื่อ APK

ไวยากรณ์สำหรับการลงชื่อ APK โดยใช้เครื่องมือ apksigner มีดังนี้

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

เมื่อลงชื่อ APK โดยใช้apksigner คุณต้องระบุ คีย์ส่วนตัวและใบรับรองของผู้ลงนาม คุณระบุข้อมูลนี้ได้ 2 วิธี ดังนี้

  • ระบุไฟล์ KeyStore โดยใช้ตัวเลือก --ks
  • ระบุไฟล์คีย์ส่วนตัวและไฟล์ใบรับรองแยกกันโดยใช้ตัวเลือก --key และ --cert ตามลำดับ ไฟล์คีย์ส่วนตัวต้องใช้รูปแบบ PKCS #8 และไฟล์ใบรับรองต้องใช้รูปแบบ X.509

โดยปกติแล้ว คุณจะลงชื่อ APK โดยใช้ผู้ลงนามเพียงรายเดียว หากต้องการ รับรอง APK โดยใช้ผู้รับรองหลายราย ให้ใช้ตัวเลือก --next-signer เพื่อแยกชุดตัวเลือกทั่วไป เพื่อใช้กับผู้รับรองแต่ละราย

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

ยืนยันลายเซ็นของ APK

ไวยากรณ์สำหรับการยืนยันว่าการยืนยันลายเซ็นของ APK ในแพลตฟอร์มที่รองรับสำเร็จแล้วมีดังนี้

apksigner verify [options] app-name.apk

หมุนเวียนคีย์การลงชื่อ

ไวยากรณ์สำหรับการหมุนเวียนลำดับชั้นของใบรับรองการลงนามหรือลำดับลายเซ็นใหม่มีดังนี้

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

ตัวเลือก

รายการต่อไปนี้ประกอบด้วยชุดตัวเลือกสำหรับแต่ละคำสั่งที่เครื่องมือ apksigner รองรับ

คำสั่งลงนาม

คำสั่ง apksigner sign มีตัวเลือกต่อไปนี้

ตัวเลือกทั่วไป

ตัวเลือกต่อไปนี้ระบุการตั้งค่าพื้นฐานที่จะใช้กับผู้ลงนาม

--out <apk-filename>
ตำแหน่งที่ต้องการบันทึก APK ที่ลงชื่อแล้ว หากไม่ได้ระบุตัวเลือกนี้อย่างชัดเจน ระบบจะลงนามแพ็กเกจ APK ในตำแหน่งเดิม ซึ่งจะเขียนทับไฟล์ APK อินพุต
--min-sdk-version <integer>
ระดับ API ของเฟรมเวิร์ก Android ที่ต่ำที่สุดที่ apksigner ใช้เพื่อ ยืนยันว่าลายเซ็นของ APK จะได้รับการยืนยัน ค่าที่สูงขึ้นจะช่วยให้เครื่องมือ ใช้พารามิเตอร์ความปลอดภัยที่เข้มงวดมากขึ้นเมื่อลงนามในแอป แต่จะจำกัด ความพร้อมใช้งานของ APK ในอุปกรณ์ที่ใช้ Android เวอร์ชันล่าสุด โดยค่าเริ่มต้น apksigner จะใช้ค่าของแอตทริบิวต์ minSdkVersion จากไฟล์ Manifest ของแอป
--max-sdk-version <integer>
ระดับ API ของเฟรมเวิร์ก Android สูงสุดที่ apksigner ใช้ เพื่อยืนยันว่าลายเซ็นของ APK จะได้รับการยืนยัน โดยค่าเริ่มต้น เครื่องมือ จะใช้ระดับ API ที่สูงที่สุดที่เป็นไปได้
--rotation-min-sdk-version <integer>
ระดับ API ต่ำสุดที่คีย์ Signing ที่หมุนเวียนของ APK ควรใช้เพื่อสร้างลายเซ็นของ APK ระบบจะใช้คีย์ Signing เดิม (ที่ไม่ได้หมุนเวียน) สำหรับ APK กับแพลตฟอร์มเวอร์ชันก่อนหน้าทั้งหมด โดยค่าเริ่มต้น ระบบจะใช้คีย์การลงนามที่หมุนเวียนซึ่งรองรับในอุปกรณ์ที่ใช้ Android 13 (API ระดับ 33) ขึ้นไปกับบล็อกการลงนาม v3.1

หมายเหตุ: หากแอปได้รับการลงนามด้วยคีย์ Signing ที่หมุนเวียน ในอุปกรณ์ที่ใช้ Android 12L (API ระดับ 32) หรือต่ำกว่า คุณ ต้องใช้ --rotation-min-sdk-version 28 เพื่อลงนามต่อไป ในแอปด้วยคีย์ Signing ที่หมุนเวียนสำหรับ Android 9 (API ระดับ 28)

--v1-signing-enabled <true | false>
กำหนดว่า apksigner จะลงนามในแพ็กเกจ APK ที่ระบุหรือไม่ โดยใช้รูปแบบการลงนามแบบเดิมที่อิงตาม JAR โดยค่าเริ่มต้น เครื่องมือจะใช้ ค่าของ --min-sdk-version และ --max-sdk-version เพื่อตัดสินใจว่าจะใช้รูปแบบ ลายเซ็นนี้เมื่อใด
--v2-signing-enabled <true | false>
กำหนดว่า apksigner จะลงนามในแพ็กเกจ APK ที่ระบุ โดยใช้ APK Signature Scheme v2 หรือไม่ โดยค่าเริ่มต้น เครื่องมือจะใช้ค่าของ --min-sdk-version และ --max-sdk-version เพื่อพิจารณา เวลาที่จะใช้รูปแบบลายเซ็นนี้
--v3-signing-enabled <true | false>
กำหนดว่า apksigner จะลงนามในแพ็กเกจ APK ที่ระบุ โดยใช้ APK Signature Scheme v3 หรือไม่ โดยค่าเริ่มต้น เครื่องมือจะใช้ค่าของ --min-sdk-version และ --max-sdk-version เพื่อพิจารณา เวลาที่จะใช้รูปแบบลายเซ็นนี้
--v4-signing-enabled <true | false | only>

กำหนดว่า apksigner จะลงนามในแพ็กเกจ APK ที่ระบุ โดยใช้ APK Signature Scheme v4 หรือไม่ รูปแบบนี้ สร้างลายเซ็นในไฟล์แยกต่างหาก (apk-name.apk.idsig) หาก true และ APK ไม่ได้ลงนาม ระบบจะสร้างลายเซ็น v2 หรือ v3 โดยอิงตามค่าของ --min-sdk-version และ --max-sdk-version จากนั้นคำสั่งจะสร้างไฟล์ .idsig โดยอิงตามเนื้อหาของ APK ที่ลงนาม

ใช้ only เพื่อสร้างเฉพาะลายเซ็น v4 โดยไม่ต้องแก้ไข APK และลายเซ็นใดๆ ที่มีอยู่ก่อนการเรียกใช้ only จะล้มเหลวหาก APK ไม่มีลายเซ็น v2 หรือ v3 อยู่แล้ว หรือหากลายเซ็นใช้คีย์อื่น ที่ไม่ใช่คีย์ที่ระบุสำหรับการเรียกใช้ปัจจุบัน

โดยค่าเริ่มต้น เครื่องมือจะใช้ค่าของ --min-sdk-version และ --max-sdk-version เพื่อพิจารณา เวลาที่จะใช้รูปแบบลายเซ็นนี้

-v, --verbose
ใช้โหมดเอาต์พุตแบบละเอียด

ตัวเลือกต่อผู้ลงนาม

ตัวเลือกต่อไปนี้ระบุการกำหนดค่าของผู้ลงนามที่เฉพาะเจาะจง ตัวเลือกเหล่านี้ไม่จำเป็นหากคุณลงนามในแอปโดยใช้ผู้ลงนามเพียงรายเดียว

--next-signer <signer-options>
ใช้เพื่อระบุตัวเลือกทั่วไปที่แตกต่างกันสำหรับผู้ลงนามแต่ละราย
--v1-signer-name <basename>
ชื่อฐานของไฟล์ที่ประกอบขึ้นเป็นลายเซ็นที่อิงตาม JAR สำหรับ ผู้ลงนามปัจจุบัน โดยค่าเริ่มต้น apksigner จะใช้นามแฝงคีย์ของ KeyStore หรือชื่อพื้นฐานของไฟล์คีย์สำหรับผู้ลงนามนี้

ตัวเลือกคีย์และใบรับรอง

ตัวเลือกต่อไปนี้ระบุคีย์ส่วนตัวและใบรับรองของผู้ลงนาม

--ks <filename>
คีย์ส่วนตัวและห่วงโซ่ใบรับรองของผู้ลงนามอยู่ในไฟล์ KeyStore ที่อิงตาม Java ที่ระบุ หากตั้งชื่อไฟล์เป็น "NONE" KeyStore ที่มีคีย์และใบรับรองก็ไม่จำเป็นต้องระบุไฟล์ ซึ่งเป็นกรณีของ PKCS #11 KeyStore บางรายการ
--ks-key-alias <alias>
ชื่อของชื่อแทนที่แสดงถึงคีย์ส่วนตัวของผู้ลงนามและ ข้อมูลใบรับรองภายใน KeyStore หาก KeyStore ที่เชื่อมโยงกับ ลายเซ็นมีคีย์หลายรายการ คุณต้องระบุตัวเลือกนี้
--ks-pass <input-format>

รหัสผ่านสำหรับคีย์สโตร์ที่มีคีย์ส่วนตัวและใบรับรองของผู้ลงนาม คุณต้องระบุรหัสผ่านเพื่อเปิด KeyStore apksigner เครื่องมือรองรับรูปแบบต่อไปนี้

  • pass:<password> – รหัสผ่านที่ระบุในบรรทัด พร้อมกับคำสั่ง apksigner sign ที่เหลือ
  • env:<name> - จัดเก็บรหัสผ่านไว้ในตัวแปรสภาพแวดล้อมที่ระบุ
  • file:<filename> – ระบบจะจัดเก็บรหัสผ่านเป็น บรรทัดเดียวในไฟล์ที่ระบุ
  • stdin – รหัสผ่านจะระบุเป็นบรรทัดเดียวใน สตรีมอินพุตมาตรฐาน ลักษณะการทำงานนี้เป็นลักษณะเริ่มต้นสำหรับ --ks-pass

หมายเหตุ: หากคุณใส่รหัสผ่านหลายรายการในไฟล์เดียวกัน ให้ระบุรหัสผ่านเหล่านั้นในบรรทัดแยกกัน apksigner เครื่องมือ จะเชื่อมโยงรหัสผ่านกับผู้ลงนามของ APK ตามลำดับที่คุณ ระบุผู้ลงนาม หากคุณระบุรหัสผ่าน 2 รายการสำหรับผู้ลงนาม apksigner จะตีความรหัสผ่านแรกเป็นรหัสผ่านของ KeyStore และรหัสผ่านที่ 2 เป็นรหัสผ่านของคีย์

--pass-encoding <charset>
รวมการเข้ารหัสอักขระที่ระบุ เช่น ibm437 หรือ utf-8 เมื่อพยายาม จัดการรหัสผ่านที่มีอักขระที่ไม่ใช่ ASCII

Keytool มักจะเข้ารหัสคลังคีย์โดยแปลงรหัสผ่านโดยใช้ชุดอักขระเริ่มต้นของคอนโซล โดยค่าเริ่มต้น apksigner จะพยายามถอดรหัสโดยใช้รหัสผ่านหลายรูปแบบ ดังนี้

  • รูปแบบ Unicode
  • แบบฟอร์มที่เข้ารหัสโดยใช้ชุดอักขระเริ่มต้นของ JVM
  • ใน Java 8 และเวอร์ชันเก่ากว่านั้น ฟอร์มจะได้รับการเข้ารหัสโดยใช้ชุดอักขระเริ่มต้นของคอนโซล
  • ใน Java 9 apksigner จะตรวจไม่พบชุดอักขระของคอนโซล คุณอาจต้องระบุ --pass-encoding เมื่อใช้รหัสผ่านที่ไม่ใช่ ASCII นอกจากนี้ คุณอาจต้องระบุตัวเลือกนี้ด้วย KeyStore ที่ keytool สร้างขึ้นในระบบปฏิบัติการอื่นหรือในภาษาอื่น

    --key-pass <input-format>

    รหัสผ่านสำหรับคีย์ส่วนตัวของผู้ลงนาม ซึ่งจำเป็นหากคีย์ส่วนตัวได้รับการปกป้องด้วยรหัสผ่าน apksigner เครื่องมือ รองรับรูปแบบต่อไปนี้

    • pass:<password> - รหัสผ่านจะระบุในบรรทัด พร้อมกับคำสั่ง apksigner sign ที่เหลือ
    • env:<name> - จัดเก็บรหัสผ่านไว้ในตัวแปรสภาพแวดล้อมที่ระบุ
    • file:<filename> – ระบบจะจัดเก็บรหัสผ่านเป็น บรรทัดเดียวในไฟล์ที่ระบุ
    • stdin – รหัสผ่านจะระบุเป็นบรรทัดเดียวใน สตรีมอินพุตมาตรฐาน ลักษณะการทำงานนี้เป็นลักษณะเริ่มต้นสำหรับ --key-pass
    --ks-type <algorithm>
    ประเภทหรืออัลกอริทึมที่เชื่อมโยงกับ KeyStore ที่มีคีย์ส่วนตัวและใบรับรองของผู้ลงนาม โดยค่าเริ่มต้น apksigner จะใช้ประเภทที่กำหนดเป็นค่าคงที่ keystore.type ใน ไฟล์พร็อพเพอร์ตี้ความปลอดภัย
    --ks-provider-name <name>
    ชื่อของผู้ให้บริการ JCA ที่จะใช้เมื่อขอการติดตั้งใช้งาน KeyStore ของผู้ลงนาม โดยค่าเริ่มต้น apksigner จะใช้ ผู้ให้บริการที่มีลำดับความสำคัญสูงสุด
    --ks-provider-class <class-name>
    ชื่อคลาสที่มีคุณสมบัติครบถ้วนของ JCA Provider ที่จะใช้เมื่อขอ การติดตั้งใช้งาน KeyStore ของผู้ลงนาม ตัวเลือกนี้เป็นทางเลือก สำหรับ --ks-provider-name โดยค่าเริ่มต้น apksigner จะใช้ผู้ให้บริการที่ระบุด้วยตัวเลือก --ks-provider-name
    --ks-provider-arg <value>
    ค่าสตริงที่จะส่งเป็นอาร์กิวเมนต์สำหรับตัวสร้างของ JCA คลาสผู้ให้บริการ คลาสนี้กำหนดด้วย ตัวเลือก --ks-provider-class โดยค่าเริ่มต้น apksigner จะใช้ตัวสร้างอาร์กิวเมนต์เป็น 0 ของคลาส
    --key <filename>
    ชื่อไฟล์ที่มีคีย์ส่วนตัวของผู้ลงนาม ไฟล์นี้ ต้องใช้รูปแบบ PKCS #8 DER หากคีย์ได้รับการป้องกันด้วยรหัสผ่าน apksigner ระบบจะแจ้งให้ป้อนรหัสผ่านโดยใช้การป้อนข้อมูลมาตรฐาน เว้นแต่คุณจะระบุรูปแบบการป้อนข้อมูลอื่นโดยใช้ตัวเลือก --key-pass
    --cert <filename>
    ชื่อของไฟล์ที่มีห่วงโซ่ใบรับรองของผู้ลงนาม ไฟล์นี้ต้องใช้รูปแบบ X.509 PEM หรือ DER

    ยืนยันคำสั่ง

    คำสั่ง apksigner verify มีตัวเลือกต่อไปนี้

    --print-certs
    แสดงข้อมูลเกี่ยวกับใบรับรองการลงนามของ APK
    --print-certs-pem
    แสดงข้อมูลเกี่ยวกับใบรับรองการลงนามของ APK และพิมพ์ PEM การเข้ารหัสของใบรับรองการลงนามแต่ละรายการไปยัง stdout
    --min-sdk-version <integer>
    ระดับ API ของเฟรมเวิร์ก Android ที่ต่ำที่สุดที่ apksigner ใช้เพื่อ ยืนยันว่าลายเซ็นของ APK จะได้รับการยืนยัน ค่าที่สูงขึ้นจะช่วยให้เครื่องมือ ใช้พารามิเตอร์ความปลอดภัยที่เข้มงวดมากขึ้นเมื่อลงนามในแอป แต่จะจำกัด ความพร้อมใช้งานของ APK ในอุปกรณ์ที่ใช้ Android เวอร์ชันล่าสุด โดยค่าเริ่มต้น apksigner จะใช้ค่าของแอตทริบิวต์ minSdkVersion จากไฟล์ Manifest ของแอป
    --max-sdk-version <integer>
    ระดับ API ของเฟรมเวิร์ก Android สูงสุดที่ apksigner ใช้ เพื่อยืนยันว่าลายเซ็นของ APK จะได้รับการยืนยัน โดยค่าเริ่มต้น เครื่องมือ จะใช้ระดับ API ที่สูงที่สุดที่เป็นไปได้
    -v, --verbose
    ใช้โหมดเอาต์พุตแบบละเอียด
    -Werr
    ถือว่าคำเตือนเป็นข้อผิดพลาด

    ตัวอย่าง

    ตัวอย่างการใช้ apksigner มีดังนี้

    ลงชื่อ APK

    ลงชื่อ APK โดยใช้ release.jks ซึ่งเป็นคีย์เดียวใน KeyStore

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

    ลงชื่อ APK โดยใช้คีย์ส่วนตัวและใบรับรองที่จัดเก็บเป็นไฟล์แยกกัน

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

    ลงนาม APK โดยใช้คีย์ 2 รายการดังนี้

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

    ลงนาม APK ด้วยคีย์การลงนามที่หมุนเวียนและ SDK เวอร์ชัน 28 ขึ้นไปที่กำหนดเป้าหมายการหมุนเวียน

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

    ลงนาม APK ด้วยคีย์การลงนามที่หมุนเวียนและ SDK เวอร์ชัน 33 ขึ้นไปที่กำหนดเป้าหมายการหมุนเวียน

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

    ยืนยันลายเซ็นของ APK

    ตรวจสอบว่าลายเซ็นของ APK คาดว่าจะได้รับการยืนยันว่าถูกต้องใน แพลตฟอร์ม Android ทั้งหมดที่ APK รองรับหรือไม่

    $ apksigner verify app.apk
    

    ตรวจสอบว่าลายเซ็นของ APK คาดว่าจะได้รับการยืนยันว่าถูกต้องใน Android 4.0.3 (API ระดับ 15) ขึ้นไปหรือไม่

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

    หมุนเวียนคีย์การลงชื่อ

    เปิดใช้ลำดับการรับรองการลงนามที่รองรับการหมุนเวียนคีย์

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

    หมุนเวียนคีย์การลงชื่ออีกครั้งโดยทำดังนี้

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