Skip to main content

การผสานรวม Java

sslTrus มี sslTrusJarsigner Java Provider ซึ่งสามารถใช้งานร่วมกับเครื่องมือ jarsigner ที่มาพร้อมกับ JDK เพื่อลงนามไฟล์ Java JAR ผ่านบริการลงนามโค้ดระยะไกล

ในระหว่างกระบวนการลงนาม คีย์ส่วนตัวสำหรับการลงนามโค้ดจะถูกเก็บไว้ใน HSM บนคลาวด์ตลอดเวลา ฝั่งโลคัลมีหน้าที่สร้างข้อมูลที่ต้องลงนามและโครงสร้างลายเซ็น จากนั้นเรียกบริการระยะไกลผ่าน sslTrusJarsigner Provider เพื่อดำเนินการลงนามด้วยคีย์ส่วนตัว

นอกจากการลงนาม JAR แล้ว sslTrusJarsigner ยังมีความสามารถในการลงนาม XMLDSig ซึ่งสามารถใช้ในสถานการณ์การลงนามดิจิทัล XML ได้

การเตรียมความพร้อม

ก่อนใช้งานโปรดเตรียม:

  • JDK 8 หรือเวอร์ชันใหม่กว่า
  • sslTrusJarsigner-<version>.jar
  • Access Key
  • Access Secret
  • หมายเลขใบรับรอง (Cert Code)
  • ไฟล์ JAR หรือไฟล์ XML ที่ต้องการลงนาม

<version> ข้อมูลประจำตัวการเข้าถึง หมายเลขใบรับรอง และเส้นทางไฟล์ในตัวอย่างของบทความนี้ จำเป็นต้องแทนที่ด้วยค่าจริง

ดาวน์โหลด sslTrusJarsigner

ดาวน์โหลดแพ็กเกจรุ่นล่าสุดจาก หน้าปล่อย sslTrusJarsigner และแตกไฟล์

แพ็กเกจที่เผยแพร่ประกอบด้วย:

sslTrusJarsigner-<version>.jar
SHA-256 校验文件

ขอแนะนำให้ตรวจสอบความสมบูรณ์ของ sslTrusJarsigner-<version>.jar โดยใช้การตรวจสอบ SHA-256 ก่อนการใช้งาน

ตรวจสอบสภาพแวดล้อมการทำงาน

ก่อนอื่นให้ยืนยันว่า jarsigner ที่มาพร้อมกับ Java และ JDK สามารถทำงานได้ตามปกติ:

java -version
jarsigner -help

ตรวจสอบเวอร์ชัน sslTrusJarsigner:

java -jar sslTrusJarsigner-<version>.jar --version

ดูวิธีใช้:

java -jar sslTrusJarsigner-<version>.jar --help

หากคำสั่ง jarsigner ไม่มีอยู่ โปรดตรวจสอบว่าติดตั้ง JDK แบบเต็มรูปแบบแล้ว ไม่ใช่เพียงสภาพแวดล้อมรันไทม์ของ Java

กำหนดค่าข้อมูลประจำตัวสำหรับการเข้าถึง

sslTrusJarsigner อ่านข้อมูลประจำตัวสำหรับการเข้าถึงและหมายเลขใบรับรองของบริการลงนามโค้ดระยะไกลผ่านตัวแปรสภาพแวดล้อม

Linux และ macOS

export SSLTRUS_JARSIGNER_ACCESS_KEY="YOUR_ACCESS_KEY"
export SSLTRUS_JARSIGNER_ACCESS_SECRET="YOUR_ACCESS_SECRET"
export SSLTRUS_JARSIGNER_CERT_CODE="YOUR_CERT_CODE"

Windows PowerShell

$env:SSLTRUS_JARSIGNER_ACCESS_KEY = "YOUR_ACCESS_KEY"
$env:SSLTRUS_JARSIGNER_ACCESS_SECRET = "YOUR_ACCESS_SECRET"
$env:SSLTRUS_JARSIGNER_CERT_CODE = "YOUR_CERT_CODE"

ถ้าหากเจ้าหน้าที่บริการให้ที่อยู่บริการเฉพาะมา ยังต้องตั้งค่า SSLTRUS_JARSIGNER_URL ด้วย

Linux และ macOS:

export SSLTRUS_JARSIGNER_URL="YOUR_SERVICE_URL"

Windows PowerShell:

$env:SSLTRUS_JARSIGNER_URL = "YOUR_SERVICE_URL"

หากไม่ได้ระบุที่อยู่บริการเฉพาะไว้ ไม่จำเป็นต้องตั้งค่าตัวแปรนี้

Access Secret ถือเป็นข้อมูลรับรองที่มีความละเอียดอ่อน ไม่ควรเขียนลงในซอร์สโค้ด ไฟล์คอนฟิกสาธารณะ หรือบันทึกการ build สำหรับสภาพแวดล้อมอัตโนมัติ แนะนำให้ฉีดผ่าน CI/CD Secret หรือกลไกการจัดการข้อมูลรับรองอื่น

การลงนาม JAR

sslTrusJarsigner ผสานรวมกับเครื่องมือ jarsigner มาตรฐานผ่านกลไก Java Security Provider

ตัวอย่างต่อไปนี้จะ:

app-unsigned.jar

หลังจากการเซ็นชื่อ ผลลัพธ์ที่ได้คือ:

app-signed.jar

JDK 9 หรือเวอร์ชันใหม่กว่า

Linux และ macOS:

jarsigner \
-keystore NONE \
-storetype SSLTRUS \
-storepass SSLTRUS \
-providerPath "sslTrusJarsigner-<version>.jar" \
-providerClass com.racent.codesign.SSLTrusProvider \
-sigalg SHA256withRSA \
-tsa http://timestamp.sectigo.com \
-signedjar "app-signed.jar" \
"app-unsigned.jar" \
"$SSLTRUS_JARSIGNER_CERT_CODE"

Windows PowerShell:

jarsigner `
-keystore NONE `
-storetype SSLTRUS `
-storepass SSLTRUS `
-providerPath "sslTrusJarsigner-<version>.jar" `
-providerClass com.racent.codesign.SSLTrusProvider `
-sigalg SHA256withRSA `
-tsa http://timestamp.sectigo.com `
-signedjar "app-signed.jar" `
"app-unsigned.jar" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"

JDK 8

วิธีการโหลด Provider ของ JDK 8 แตกต่างจาก JDK 9 และเวอร์ชันที่สูงกว่า

ขั้นแรกตรวจสอบ:

JAVA_HOME

ชี้ไปยังไดเรกทอรีการติดตั้ง JDK 8 แบบเต็ม

Linux และ macOS:

jarsigner \
-J-cp \
-J"$JAVA_HOME/lib/tools.jar:sslTrusJarsigner-<version>.jar" \
-keystore NONE \
-storetype SSLTRUS \
-storepass SSLTRUS \
-providerClass com.racent.codesign.SSLTrusProvider \
-sigalg SHA256withRSA \
-tsa http://timestamp.sectigo.com \
-signedjar "app-signed.jar" \
"app-unsigned.jar" \
"$SSLTRUS_JARSIGNER_CERT_CODE"

Windows PowerShell:

jarsigner `
-J-cp `
"-J$env:JAVA_HOME\lib\tools.jar;sslTrusJarsigner-<version>.jar" `
-keystore NONE `
-storetype SSLTRUS `
-storepass SSLTRUS `
-providerClass com.racent.codesign.SSLTrusProvider `
-sigalg SHA256withRSA `
-tsa http://timestamp.sectigo.com `
-signedjar "app-signed.jar" `
"app-unsigned.jar" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"

สิ่งที่ต้องระวังในการใช้งาน:

  • หมายเลขใบรับรองที่อยู่ท้ายคำสั่งต้องตรงกับ SSLTRUS_JARSIGNER_CERT_CODE
  • แนะนำให้ใช้ -signedjar เพื่อส่งออกไปยังไฟล์ใหม่ หลีกเลี่ยงการเขียนทับไฟล์ JAR เดิม
  • ตัวอย่างใช้ SHA256withRSA เพื่อทำการลงนามโค้ดให้เสร็จสมบูรณ์
  • เมื่อไม่ต้องการประทับเวลา สามารถลบ -tsa และที่อยู่ของบริการประทับเวลาที่อยู่ถัดไปออกได้

การประทับเวลา

แนะนำให้เพิ่มการประทับเวลาที่เชื่อถือได้ให้กับลายเซ็นของไฟล์ JAR ที่จะเผยแพร่อย่างเป็นทางการ

ในตัวอย่างใช้:

http://timestamp.sectigo.com

พารามิเตอร์ที่เกี่ยวข้อง:

-tsa http://timestamp.sectigo.com

การประทับเวลาใช้เพื่อพิสูจน์เวลาที่เกิดการลงนาม โดยจะไม่อัปโหลดไฟล์ JAR ต้นฉบับไปยังเซิร์ฟเวอร์ประทับเวลา

หากต้องการใช้บริการประทับเวลาอื่น สามารถแทนที่ที่อยู่หลัง -tsa ด้วยที่อยู่ TSA ที่สอดคล้องกับนโยบายการลงนามจริง

เกี่ยวกับบริการประทับเวลาที่แตกต่างกันและการเลือกใช้ในสภาพแวดล้อมการผลิต โปรดดู เอกสารอ้างอิง

ลายเซ็น XML

sslTrusJarsigner ยังมีความสามารถด้านลายเซ็นดิจิทัล XML

ไฟล์ XML สามารถสร้าง XMLDSig Enveloped Signature ผ่านคำสั่ง sign-xml

ในระหว่างกระบวนการลงนาม ฝั่งภายในจะรับผิดชอบสร้างโครงสร้างไดเจสต์และลายเซ็นที่จำเป็นสำหรับ XMLDSig ส่วนการลงนามด้วยคีย์ส่วนตัว RSA จริงจะดำเนินการโดยบริการลงนามโค้ดระยะไกล

Linux และ macOS

java -jar sslTrusJarsigner-<version>.jar \
sign-xml \
"input.xml" \
"signed.xml" \
"$SSLTRUS_JARSIGNER_CERT_CODE"

Windows PowerShell

java -jar sslTrusJarsigner-<version>.jar `
sign-xml `
"input.xml" `
"signed.xml" `
"$env:SSLTRUS_JARSIGNER_CERT_CODE"

ผลลัพธ์ที่แสดงโดยค่าเริ่มต้น KeyInfo จะมีเฉพาะ leaf certificate เท่านั้น หากผู้รับต้องการให้ XML มี certificate chain ครบถ้วน สามารถเพิ่มพารามิเตอร์ --full-chain ต่อท้ายคำสั่งได้

หลังจากดำเนินการเสร็จสิ้น:

input.xml

สำหรับไฟล์ XML ต้นฉบับ

signed.xml

สำหรับไฟล์เอาต์พุตที่มีลายเซ็นดิจิทัล XML

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

สร้างไฟล์สำหรับการตรวจสอบ

หลังจากเซ็นชื่อเสร็จสิ้น คุณสามารถสร้างไฟล์ JKS สำหรับตรวจสอบลายเซ็นได้

Linux และ macOS:

java -jar sslTrusJarsigner-<version>.jar \
generate-keystore \
"$SSLTRUS_JARSIGNER_CERT_CODE" \
"verify.jks" \
"SSLTRUS"

Windows PowerShell:

java -jar sslTrusJarsigner-<version>.jar `
generate-keystore `
"$env:SSLTRUS_JARSIGNER_CERT_CODE" `
"verify.jks" `
"SSLTRUS"

สร้าง:

verify.jks

ไฟล์นี้ใช้สำหรับการตรวจสอบลายเซ็นเท่านั้น ไม่สามารถใช้สำหรับการลงนามโค้ดได้

คีย์ส่วนตัวสำหรับการลงนามโค้ดยังคงถูกเก็บไว้ใน HSM ระยะไกล และจะไม่ถูกเขียนลงใน verify.jks

ตรวจสอบลายเซ็น JAR

ใช้ verify.jks ที่สร้างขึ้นเพื่อตรวจสอบลายเซ็น:

jarsigner \
-verify \
-verbose \
-certs \
-keystore "verify.jks" \
-storetype JKS \
-storepass "SSLTRUS" \
"app-signed.jar"

หากต้องการเพียงแค่ดูข้อมูลลายเซ็นที่มีอยู่แล้วใน JAR ให้รันคำสั่ง:

jarsigner -verify -verbose -certs "app-signed.jar"

การตรวจสอบลายเซ็นเพียงตรวจสอบลายเซ็นที่มีอยู่เท่านั้น จะไม่เรียกใช้คีย์ส่วนตัวระยะไกลอีกครั้งเพื่อดำเนินการลงนาม

จำนวนครั้งในการลงนาม

จำนวนครั้งในการลงนามของ Jarsigner คำนวณตามการดำเนินการลงนามระยะไกลที่สำเร็จจริง

โดยทั่วไป:

การดำเนินการจำนวนครั้งในการลงนาม
ลงนาม JAR หนึ่งไฟล์สำเร็จหนึ่งครั้ง1 ครั้ง
ลงนาม JAR 3 ไฟล์แยกกัน3 ครั้ง
ดำเนินการลงนามอีกครั้งกับ JAR ไฟล์เดิมเพิ่มอีก 1 ครั้ง
jarsigner -verify ตรวจสอบลายเซ็น0 ครั้ง
สร้าง verify.jks0 ครั้ง

ดังนั้น จำนวนครั้งในการลงนามขึ้นอยู่กับจำนวนครั้งของการดำเนินการลงนามที่สำเร็จจริงเป็นหลัก ไม่ใช่จำนวนไฟล์ซอร์สโค้ดของโปรเจกต์ Java

สำหรับกฎโดยละเอียด โปรดดู เอกสารอ้างอิง

คำถามที่พบบ่อย

ขาด Access Key, Access Secret หรือหมายเลขใบรับรอง

ยืนยันว่าเทอร์มินัลปัจจุบันได้ตั้งค่าไว้แล้ว:

SSLTRUS_JARSIGNER_ACCESS_KEY
SSLTRUS_JARSIGNER_ACCESS_SECRET
SSLTRUS_JARSIGNER_CERT_CODE

After setting the environment variables, you need to execute the signing command in the same terminal session.

Invalid option: -providerPath

If the following appears:

Invalid option: -providerPath

โดยปกติจะระบุว่ากำลังใช้ JDK 8 อยู่

JDK 8 ไม่ใช้พารามิเตอร์ -providerPath จากตัวอย่างใน JDK 9 ขึ้นไป โปรดใช้คำสั่งสำหรับ JDK 8 ที่ให้ไว้ในบทความนี้แทน

ไม่สามารถโหลด SSLTrusProvider ได้

หากมีการแจ้งเตือนว่าไม่สามารถโหลดได้:

com.racent.codesign.SSLTrusProvider

โปรดตรวจสอบ:

  • เส้นทาง sslTrusJarsigner-<version>.jar ถูกต้องหรือไม่
  • หมายเลขเวอร์ชันในชื่อไฟล์ตรงกับไฟล์จริงหรือไม่
  • ในสภาพแวดล้อม JDK 8 JAVA_HOME ชี้ไปยัง JDK แบบเต็มหรือไม่

ไม่พบใบรับรองหรือ alias

โปรดตรวจสอบ:

  • หมายเลขใบรับรองถูกต้องหรือไม่
  • หมายเลขใบรับรองที่ระบุไว้ท้ายคำสั่งตรงกับ SSLTRUS_JARSIGNER_CERT_CODE หรือไม่
  • Access Key และ Access Secret ปัจจุบันมีสิทธิ์ใช้งานใบรับรองดังกล่าวหรือไม่

คำขอลงนามระยะไกลล้มเหลว

โปรดตรวจสอบ:

  • เครือข่ายปัจจุบันสามารถเข้าถึงบริการลงนามโค้ดระยะไกลได้หรือไม่
  • การตั้งค่าพร็อกซี ไฟร์วอลล์ และ DNS ทำงานปกติหรือไม่
  • Access Key และ Access Secret ถูกต้องหรือไม่
  • หมายเลขใบรับรองถูกต้องหรือไม่
  • หากใช้ที่อยู่บริการเฉพาะ SSLTRUS_JARSIGNER_URL ได้รับการกำหนดค่าตามข้อมูลการส่งมอบจริงหรือไม่

เมื่อตรวจสอบปัญหา สามารถเก็บข้อมูลข้อผิดพลาดแบบเต็มไว้ได้ แต่ก่อนส่งบันทึกหรือภาพหน้าจอข้อผิดพลาด ควรลบหรือปกปิดข้อมูลรับรองที่ละเอียดอ่อน เช่น Access Secret

การประทับเวลาไม่สำเร็จ

ยืนยันว่าเครือข่ายปัจจุบันสามารถเข้าถึงเซิร์ฟเวอร์ประทับเวลาที่ระบุโดย -tsa ได้

หากธุรกิจอนุญาต สามารถนำออกชั่วคราวได้:

-tsa <URL>

ดำเนินการเซ็นลายเซ็นอีกครั้ง เพื่อตรวจสอบว่าปัญหาเกิดขึ้นที่ขั้นตอนการเซ็นโค้ดระยะไกลหรือการร้องขอ timestamp

ข้อแนะนำด้านความปลอดภัย

ระหว่างการผสานรวม Java ควรคำนึงถึงสิ่งต่อไปนี้:

  • ควรเก็บ Access Secret ไว้เป็นข้อมูลรับรองที่มีความละเอียดอ่อน
  • ไม่ควรคอมมิตข้อมูลรับรองการเข้าถึงลงใน Git repository
  • ไม่ควรแสดง Access Secret แบบเต็มในบันทึก (log)
  • verify.jks ใช้สำหรับการตรวจสอบเท่านั้น และไม่มีคีย์ส่วนตัวที่ใช้สำหรับการเซ็นระยะไกล
  • sslTrusJarsigner Provider ในเครื่องไม่บันทึกคีย์ส่วนตัวสำหรับการเซ็นโค้ด
  • การเซ็นด้วยคีย์ส่วนตัวจะดำเนินการโดยบริการเซ็นโค้ดระยะไกลเสมอ
  • สำหรับสภาพแวดล้อมอัตโนมัติ แนะนำให้ใช้ CI/CD Secret หรือระบบจัดการข้อมูลรับรองเฉพาะเพื่อฉีดข้อมูลรับรองการเข้าถึง

วิธีผสานรวมที่เกี่ยวข้อง

หากไฟล์ที่ต้องการเซ็นไม่ใช่ไฟล์ Java JAR หรือ XML สามารถเลือกวิธีผสานรวมอื่นตามสถานการณ์จริงได้:

สถานการณ์วิธีผสานรวม
เซ็นไฟล์ EXE, DLL, MSI ฯลฯ โดยตรงผ่านบรรทัดคำสั่งเครื่องมือไคลเอนต์
เครื่องมือ Windows เช่น Microsoft SignTool, Visual StudioWindows Provider
งานสร้างอัตโนมัติ เช่น GitHub Actions, Electron BuilderCI/CD และเครื่องมือ build
พัฒนาไคลเอนต์การเซ็นระยะไกลด้วยตนเองการผสานรวม API