การผสานรวม API
sslTrus มี Remote Code Signing API สำหรับนักพัฒนาที่ต้องการพัฒนาซิกเนเจอร์ไคลเอนต์ ระบบ build หรือโปรแกรมรวมซิกเนเจอร์อื่น ๆ ด้วยตนเอง
API รับค่า digest ของไฟล์ที่คำนวณโดยไคลเอนต์ จากนั้นบริการ Remote Code Signing จะใช้ใบรับรอง Code Signing ที่ระบุเพื่อดำเนินการเซ็นด้วย private key และส่งคืนผลลัพธ์การเซ็น
ไคลเอนต์รับผิดชอบ:
- คำนวณ digest ของข้อมูลที่ต้องการเซ็น
- สร้างโครงสร้างลายเซ็นที่ไฟล์เป้าหมายต้องการ
- เรียกใช้อินเทอร์เฟซการเซ็นระยะไกล
- เขียนผลลัพธ์การเซ็นที่ส่งคืนลงในไฟล์เป้าหมายหรือโครงสร้างลายเซ็น
- รายงานผลการประมวลผลสุดท้ายของไคลเอนต์ตามความจำเป็น
Private key ของ Code Signing จะถูกเก็บไว้ใน HSM บนคลาวด์เสมอ และจะไม่ถูกส่งคืนให้ไคลเอนต์ผ่าน API
ที่อยู่สำหรับเชื่อมต่อ
ที่อยู่เริ่มต้นของสภาพแวดล้อมการผลิต:
https://ssl.face.racent.com
สภาพแวดล้อม NICSRS:
https://ssl.face.nicsrs.com
อินเทอร์เฟซการลงนามแบบสมบูรณ์:
POST https://ssl.face.racent.com/v1/codesign/sign
อินเทอร์เฟซการรายงานผล:
POST https://ssl.face.racent.com/v1/codesign/report-sign
หากสภาพแวดล้อมที่ให้บริการจริงใช้ที่อยู่บริการอื่น โปรดยึดตามที่อยู่ที่ทีมส่งมอบหรือฝ่ายปฏิบัติการให้ไว้
การยืนยันตัวตน
API ใช้ HTTP Basic Auth
ความสัมพันธ์ที่สอดคล้องกัน:
Username = Access Key
Password = Access Secret
ส่วนหัวคำขอ:
Authorization: Basic <base64(accessKey:accessSecret)>
ตัวอย่างเช่น:
printf "%s:%s" "$ACCESS_KEY" "$ACCESS_SECRET" | base64
เมื่อใช้งานจริง curl สามารถระบุโดยตรงผ่านพารามิเตอร์ -u ได้:
curl -u "$ACCESS_KEY:$ACCESS_SECRET"
Access Secret เป็นข้อมูลรับรองที่มีความละเอียดอ่อน ไม่ควรเขียนลงในซอร์สโค้ด ไฟล์กำหนดค่าสาธารณะ ล็อก หรือหน้าเว็บส่วนหน้า
รูปแบบคำขอทั่วไป
การใช้งาน API:
HTTPS
POST
JSON
ส่วนหัวคำขอ:
Content-Type: application/json
Accept: application/json
Authorization: Basic <credentials>
รูปแบบการตอบกลับทั่วไป
API จะส่งกลับโครงสร้าง JSON แบบรวมศูนย์:
{
"code": 0,
"message": "ok",
"data": {}
}
คำอธิบายฟิลด์:
| ฟิลด์ | ชนิด | คำอธิบาย |
|---|---|---|
code | integer | รหัสสถานะทางธุรกิจ 0 หมายถึงสำเร็จ |
message | string | สถานะหรือข้อความแสดงข้อผิดพลาด |
data | object | ข้อมูลธุรกิจของอินเทอร์เฟซ |
ไคลเอนต์จำเป็นต้องตรวจสอบทั้งรหัสสถานะ HTTP และรหัสสถานะทางธุรกิจพร้อมกัน
แนะนำให้ดำเนินการตามวิธีต่อไปนี้:
HTTP 非 2xx
↓
HTTP 请求失败
HTTP 2xx + code != 0
↓
业务失败
HTTP 2xx + code == 0
↓
读取 data
อย่าตัดสินว่าคำขอการเซ็นชื่อสำเร็จเพียงเพราะ HTTP 200
อินเทอร์เฟซการเซ็นชื่อ
อินเทอร์เฟซ:
POST /v1/codesign/sign
อินเทอร์เฟซนี้ใช้สำหรับส่งไดเจสต์ที่รอการลงนาม และรับผลการลงนามด้วยคีย์ส่วนตัวระยะไกล
พารามิเตอร์คำขอ
ตัวอย่างคำขอ:
{
"code": "CERT_CODE",
"digest": "BASE64_ENCODED_HASH",
"algorithm": "SHA256",
"padding": "PKCS1",
"extra": {
"platform": "windows/amd64",
"version": "1.0.0",
"revision": "abcdef0",
"time": "2026-06-12T10:00:00+08:00",
"hostname": "build-host-01",
"signing_filename": "Example.exe",
"signing_filesize": 1048576
}
}
พารามิเตอร์หลัก:
| พารามิเตอร์ | ชนิด | จำเป็น | คำอธิบาย |
|---|---|---|---|
code | string | ใช่ | หมายเลขใบรับรองการลงนามโค้ด |
digest | string | ใช่ | การเข้ารหัส Base64 ของไบต์ดิบของไดเจสต์ที่รอการลงนาม |
algorithm | string | ใช่ | อัลกอริทึมไดเจสต์ |
padding | string | ใช่ | วิธีการแพ็ดดิ้ง RSA ปัจจุบันคงที่เป็น PKCS1 |
extra | object | ไม่ | ข้อมูลบริบทและตรวจสอบฝั่งไคลเอ็นต์ |
อัลกอริทึมไดเจสต์
ปัจจุบันรองรับ:
SHA1
SHA256
ตัวอย่างเช่น เมื่อใช้ SHA-256:
{
"algorithm": "SHA256"
}
algorithm ต้องสอดคล้องกับอัลกอริทึมการย่อความ (digest) ที่ใช้จริงของ digest
รูปแบบ digest
digest ต้องเป็น:
แฮชไบต์ดิบ → Base64
ไม่ใช่:
文件内容 Base64
ไม่ใช่เช่นกัน:
十六进制哈希字符串
ตัวอย่างเช่น หากไดเจสต์ SHA-256 มีขนาด 32 ไบต์ ควรนำไบต์ดิบทั้ง 32 ไบต์ไปเข้ารหัส Base64 ก่อนส่งให้กับอินเทอร์เฟซ
padding
ปัจจุบันใช้ค่าคงที่:
PKCS1
นั่นคือ:
{
"padding": "PKCS1"
}
อย่าส่งผ่านวิธีการเติมข้อมูลอื่น ๆ
extra
extra ใช้สำหรับบันทึกบริบทของไคลเอนต์ ข้อมูลการตรวจสอบ และช่วยในการตรวจแก้ปัญหา
รองรับ:
| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
platform | string | แพลตฟอร์มของไคลเอนต์ |
version | string | เวอร์ชันของไคลเอนต์ |
revision | string | รีวิชันการ build ของไคลเอนต์ |
time | string | เวลาที่ build หรือเวลาที่ฝั่งคำขอบันทึก |
hostname | string | ชื่อโฮสต์ที่ส่งคำขอ |
signing_filename | string | ชื่อไฟล์ที่ลงนามหรือพาธภายในเครื่อง |
signing_filesize | integer | ขนาดไฟล์ หน่วยเป็นไบต์ |
ตัวอย่างเช่น:
{
"extra": {
"platform": "linux/amd64",
"version": "1.2.0",
"hostname": "github-runner-01",
"signing_filename": "app.exe",
"signing_filesize": 5242880
}
}
หาก signing_filename มีไดเรกทอรีภายใน ชื่อผู้ใช้ หรือข้อมูลละเอียดอ่อนอื่น ๆ ขอแนะนำให้ทำการปกปิดข้อมูลตามนโยบายความปลอดภัยของฝั่งลูกค้า
ตัวอย่างคำขอลงนาม
ใช้ curl:
curl -u "$ACCESS_KEY:$ACCESS_SECRET" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"code": "CERT_CODE",
"digest": "BASE64_ENCODED_HASH",
"algorithm": "SHA256",
"padding": "PKCS1",
"extra": {
"platform": "linux/amd64",
"version": "1.0.0",
"hostname": "build-host-01",
"signing_filename": "Example.exe",
"signing_filesize": 1048576
}
}' \
https://ssl.face.racent.com/v1/codesign/sign
ลายเซ็นตอบกลับ
การตอบกลับที่สำเร็จ:
{
"code": 0,
"message": "ok",
"data": {
"id": "735985894427246592",
"signature": "BASE64_ENCODED_SIGNATURE"
}
}
ช่องข้อมูลที่ส่งคืน:
| ช่องข้อมูล | ประเภท | คำอธิบาย |
|---|---|---|
id | string | รหัสบันทึกลายเซ็น |
signature | string | การเข้ารหัส Base64 ของผลลัพธ์ลายเซ็น RSA |
สำหรับความสามารถในการลงนามจริง ไคลเอนต์ส่วนใหญ่ใช้:
data.signature
หากจำเป็นต้องรายงานสถานะสุดท้ายหลังจากประมวลผลในเครื่องเสร็จสิ้น ยังต้องบันทึก:
data.id
ขั้นตอนการประมวลผลฝั่งไคลเอ็นต์
ขั้นตอนทั่วไป:
读取待签名文件
↓
按照目标格式生成待签名数据
↓
计算摘要
↓
Base64 编码摘要
↓
POST /v1/codesign/sign
↓
获得 signature
↓
构造最终签名结构
↓
写回目标文件
↓
POST /v1/codesign/report-sign
สิ่งที่ต้องระวัง:
/v1/codesign/sign
รับผิดชอบเฉพาะการลงนามด้วยคีย์ส่วนตัวระยะไกลในระดับล่างเท่านั้น
การจัดโครงสร้างลายเซ็นของ PE Authenticode, JAR, PDF หรือรูปแบบไฟล์อื่น ๆ นั้น ไคลเอ็นต์จะจัดการเองตามรูปแบบเป้าหมาย
รายงานผลการลงนาม
อินเทอร์เฟซ:
POST /v1/codesign/report-sign
หลังจากไคลเอนต์ได้รับผลการลงนามระยะไกลแล้ว ยังอาจเกิดความล้มเหลวในกระบวนการถัดไปได้ เช่น:
- การสร้างโครงสร้างลายเซ็นสุดท้ายล้มเหลว
- การเขียนไฟล์เป้าหมายล้มเหลว
- สิทธิ์ของไฟล์ในเครื่องไม่ถูกต้อง
- ข้อผิดพลาดในการประมวลผลของไคลเอนต์ในภายหลัง
คุณสามารถใช้อินเทอร์เฟซนี้เพื่อส่งสถานะการประมวลผลขั้นสุดท้ายกลับไปยังฝั่งเซิร์ฟเวอร์ได้
พารามิเตอร์คำขอ
{
"id": "735985894427246592",
"status": 1
}
参数:
| ฟิลด์ | ชนิด | จำเป็น | คำอธิบาย |
|---|---|---|---|
id | string | ใช่ | /v1/codesign/sign รหัสบันทึกลายเซ็นที่ส่งกลับ |
status | integer | ใช่ | สถานะการประมวลผลสุดท้ายของไคลเอนต์ |
ค่าสถานะ:
| สถานะ | คำอธิบาย |
|---|---|
1 | ไคลเอนต์ประมวลผลสำเร็จในขั้นสุดท้าย |
2 | ไคลเอนต์ประมวลผลล้มเหลวในขั้นสุดท้าย |
ตัวอย่างคำขอ
curl -u "$ACCESS_KEY:$ACCESS_SECRET" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"id": "735985894427246592",
"status": 1
}' \
https://ssl.face.racent.com/v1/codesign/report-sign
การตอบกลับเมื่อสำเร็จ
{
"code": 0,
"message": "ok",
"data": null
}
จำนวนครั้งการลงนาม
จำนวนครั้งการลงนาม API นับตามความสำเร็จของการดำเนินการลงนามระยะไกล
เมื่อ:
HTTP 2xx
code == 0
data.signature 非空
เมื่อตรงตามเงื่อนไขทั้งหมดพร้อมกัน จะถือว่าเป็นการลงนามสำเร็จหนึ่งครั้ง:
签名次数 +1
以下กรณีไม่นับจำนวนครั้งการลงนาม:
- การตรวจสอบสิทธิ์ล้มเหลว
- พารามิเตอร์ไม่ถูกต้อง
- คำขอเครือข่ายล้มเหลว
- คำขอทางธุรกิจล้มเหลว
- เซิร์ฟเวอร์ไม่สามารถส่งคืนเนื้อหาลายเซ็นได้สำเร็จ
ข้อควรระวังเป็นพิเศษ:
/v1/codesign/report-sign
เป็นเพียงการรายงานสถานะการประมวลผลขั้นสุดท้ายของไคลเอ็นต์เท่านั้น ไม่ใช่การดำเนินการลงนามใหม่ และไม่เพิ่มหรือลดจำนวนครั้งของการลงนาม
แม้ว่าไคลเอ็นต์จะได้รับผลการลงนามระยะไกลสำเร็จแล้ว แต่ต่อมาเกิดความล้มเหลวขณะเขียนไฟล์ในเครื่อง การลงนามด้วยคีย์ส่วนตัวระยะไกลที่สำเร็จก่อนหน้านี้ก็ยังนับเป็นหนึ่งครั้งในการลงนามแล้ว
โปรดดู เอกสารอ้างอิง สำหรับกฎการนับเพิ่มเติม
การจัดการข้อผิดพลาด
ไคลเอ็นต์ควรจัดการแยกกันดังนี้:
- ข้อผิดพลาดเครือข่าย
- ข้อผิดพลาด HTTP
- ข้อผิดพลาดทางธุรกิจของ API
- ข้อผิดพลาดการประมวลผลในเครื่องของไคลเอ็นต์
การตรวจสอบสิทธิ์ล้มเหลว
ตัวอย่างเช่น:
{
"code": 401,
"message": "unauthorized",
"data": null
}
应ตรวจสอบ:
- Access Key ถูกต้องหรือไม่
- Access Secret ถูกต้องหรือไม่
- คำขอมีการแนบ Authorization Header อย่างถูกต้องหรือไม่
ข้อผิดพลาดของพารามิเตอร์
ตัวอย่างเช่น:
{
"code": 400,
"message": "invalid request",
"data": null
}
ควรตรวจสอบเป็นพิเศษ:
codeถูกต้องหรือไม่digestเป็น Base64 ที่ถูกต้องหรือไม่algorithmตรงกับบทสรุปหรือไม่paddingเป็นPKCS1หรือไม่
ไคลเอนต์ไม่ควรพึ่งพาค่าคงที่:
message
สตริงใช้เพื่อควบคุมตรรกะของโปรแกรม
การประมวลผลทางธุรกิจควรยึดตามรหัสสถานะและข้อกำหนดของอินเทอร์เฟซเป็นหลัก
การหมดเวลาและการลองใหม่
เมื่อเรียกอินเทอร์เฟซการลงนามระยะไกล ควรตั้งค่าการหมดเวลาของเครือข่ายอย่างเหมาะสม
เมื่อจำเป็นต้องลองใหม่ ควรให้ความสนใจเป็นพิเศษกับ:
签名接口不是普通查询接口
หากไคลเอนต์ไม่ได้รับการตอบกลับเนื่องจากเครือข่ายขัดข้อง ไม่ได้หมายความว่าฝั่งเซิร์ฟเวอร์ยังไม่ได้ดำเนินการลงนามเสมอไป
ดังนั้น เมื่อออกแบบกลไกการลองใหม่โดยอัตโนมัติ ควรหลีกเลี่ยงการส่งคำขอลงนามซ้ำอย่างไม่จำกัดหรือไม่มีเงื่อนไข
แนะนำให้บันทึกแยกกันดังนี้:
- เวลาเริ่มต้นของคำขอ
- หมายเลขใบรับรองเป้าหมาย
- ตัวระบุสรุปข้อมูล
- สถานะ HTTP
- รหัสสถานะทางธุรกิจ
- ID บันทึกการลงนามที่ส่งกลับ
- สถานะการประมวลผลขั้นสุดท้ายของไคลเอนต์
อย่าบันทึก Access Secret แบบเต็มในบันทึก
บันทึกและการตรวจสอบ
แนะนำให้บันทึกบริบทการลงนามที่จำเป็น เช่น:
certificate code
platform
client version
hostname
filename
filesize
sign record id
result
สำหรับ:
digest
signature
ข้อมูลที่มีความยาวมากเช่นนี้ ไม่แนะนำให้เขียนลงในบันทึกทั่วไปทั้งหมด
สามารถบันทึกได้ดังนี้:
- ความยาว
- ค่าแฮช
- คำนำหน้าและคำต่อท้ายหลังการปกปิดข้อมูล
เส้นทางไฟล์อาจมีชื่อผู้ใช้ ชื่อโปรเจกต์ หรือข้อมูลไดเรกทอรีภายในรวมอยู่ด้วย ควรพิจารณาว่าจะปกปิดข้อมูลหรือไม่ตามข้อกำหนดด้านความปลอดภัยที่แท้จริง
คำอธิบายด้านความปลอดภัย
เมื่อผสานรวม API แนะนำให้ปฏิบัติตามหลักการต่อไปนี้:
- ไม่ควรบันทึก Access Secret ไว้ในโค้ดฝั่งฟรอนต์เอนด์
- ไม่ควรคอมมิต Access Secret ไปยัง Git repository
- อย่าบันทึก Authorization Header แบบเต็มในบันทึกทั่วไป
- อย่าบันทึก Access Secret แบบเต็ม
- ปกปิดข้อมูลที่จำเป็นในบันทึกสำหรับ
digestและsignature - เรียกใช้บริการลงนามระยะไกลผ่าน HTTPS
- ฝั่งไคลเอ็นต์ควรตรวจสอบสถานะ HTTP และสถานะทางธุรกิจ
- ตั้งค่านโยบายการหมดเวลาและการลองใหม่ที่สมเหตุสมผลสำหรับคำขอเครือข่าย
API การลงนามโค้ดระยะไกลจะส่งคืนผลลัพธ์การลงนาม ไม่ใช่คีย์ส่วนตัว
คีย์ส่วนตัวสำหรับการลงนามโค้ดจะถูกเก็บรักษาไว้ใน HSM ระยะไกลเสมอ
เมื่อใดควรใช้ API
หากวิธีการผสานรวมที่มีอยู่ตอบโจทย์ความต้องการแล้ว โดยทั่วไปสามารถใช้เครื่องมือที่เกี่ยวข้องได้โดยตรง
| สถานการณ์ | วิธีที่แนะนำ |
|---|---|
| ลงนามไฟล์ EXE, DLL, MSI ฯลฯ โดยตรง | เครื่องมือไคลเอ็นต์ |
| ซอฟต์แวร์ Windows เช่น Microsoft SignTool, Visual Studio | Windows Provider |
| การลงนามไฟล์ JAR | การผสานรวม Java |
| การบิวด์อัตโนมัติ เช่น GitHub Actions, Electron Builder | CI/CD และเครื่องมือบิวด์ |
| พัฒนาไคลเอ็นต์การลงนามด้วยตนเอง | API |
| นำกระบวนการลงนามรูปแบบไฟล์ไปใช้ด้วยตนเอง | API |
| ต้องการควบคุมค่าแฮชและผลลัพธ์การลงนามโดยตรง | API |
API เหมาะสำหรับนักพัฒนาที่ต้องการควบคุมกระบวนการลงนามระดับล่างมากกว่า
หากเพียงต้องการลงนามโค้ดกับไฟล์ทั่วไป การใช้ไคลเอ็นต์หรือ Provider มาตรฐานที่มีอยู่ก่อนจะช่วยลดภาระในการจัดการรูปแบบไฟล์ลงนามด้วยตนเอง