การผสานรวม API
sslTrus มี API การลงนามโค้ดระยะไกล เหมาะสำหรับนักพัฒนาที่ต้องการพัฒนาซอฟต์แวร์ไคลเอนต์สำหรับการลงนาม ระบบบิลด์ หรือโปรแกรมบูรณาการการลงนามอื่น ๆ ด้วยตนเอง
API รับค่าแฮชของไฟล์ที่คำนวณโดยไคลเอนต์ จากนั้นบริการลงนามโค้ดระยะไกลจะใช้ใบรับรองการลงนามโค้ดที่ระบุเพื่อลงนามด้วยคีย์ส่วนตัวและส่งคืนผลลัพธ์การลงนาม
ไคลเอนต์มีหน้าที่รับผิดชอบดังนี้:
- คำนวณค่าแฮชของข้อมูลที่ต้องการลงนาม
- สร้างโครงสร้างลายเซ็นที่จำเป็นสำหรับไฟล์เป้าหมาย
- เรียกใช้อินเทอร์เฟซการลงนามระยะไกล
- เขียนผลลัพธ์การลงนามที่ส่งกลับลงในไฟล์เป้าหมายหรือโครงสร้างลายเซ็น
- รายงานผลการประมวลผลขั้นสุดท้ายของไคลเอนต์ตามความจำเป็น
คีย์ส่วนตัวสำหรับการลงนามโค้ดจะถูกเก็บไว้ใน 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 เป็นข้อมูลประจำตัวที่ละเอียดอ่อน ไม่ควรเขียนลงในซอร์สโค้ด ไฟล์กำหนดค่าสาธารณะ บันทึก日志 หรือหน้าฝั่ง frontend
รูปแบบคำขอทั่วไป
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
SHA384
SHA512
เช่น เมื่อใช้ SHA-256:
{
"algorithm": "SHA256"
}
algorithm ต้องสอดคล้องกับอัลกอริทึมการย่อข้อมูลที่ใช้งานจริงโดย digest
รูปแบบ digest
digest ต้องเป็น:
แฮชไบต์ดิบ → Base64
ไม่ใช่:
文件内容 Base64
ไม่ใช่เช่นกัน:
十六进制哈希字符串
เช่น หากค่าแฮช SHA-256 มีขนาด 32 ไบต์ ควรนำไบต์ดิบทั้ง 32 ไบต์นี้ไปเข้ารหัส Base64 ก่อนส่งให้กับ API
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 | ID ของบันทึกลายเซ็น |
signature | string | ผลลัพธ์ลายเซ็น RSA ที่เข้ารหัส Base64 |
สำหรับความสามารถในการลงนามจริง ไคลเอนต์ส่วนใหญ่ใช้:
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 返回的签名记录 ID |
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
- รหัสสถานะทางธุรกิจ
- หมายเลขบันทึกการลงนามที่ส่งกลับ
- สถานะการประมวลผลสุดท้ายของไคลเอนต์
อย่าบันทึก 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 มาตรฐานก่อนจะช่วยลดภาระงานในการจัดการรูปแบบไฟล์ลงนามด้วยตนเอง