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 属于敏感凭证,不应写入源代码、公开配置文件、日志或前端页面。
通用请求格式
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 编码后传入接口。
padding
当前固定使用:
PKCS1
即:
{
"padding": "PKCS1"
}
不要传入其他填充方式。
extra
extra 用于记录客户端上下文、审计信息以及辅助问题排查。
支持:
| 字段 | 类型 | 说明 |
|---|---|---|
platform | string | 客户端平台 |
version | string | 客户端版本 |
revision | string | 客户端构建 revision |
time | string | 构建时间或请求侧记录时间 |
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 状态。
- 业务状态码。
- 返回签名记录 ID。
- 客户端最终处理状态。
不要在日志中记录完整 Access Secret。
日志与审计
建议记录必要的签名上下文,例如:
certificate code
platform
client version
hostname
filename
filesize
sign record id
result
对于:
digest
signature
这类长度较大的数据,不建议完整写入普通日志。
可以记录:
- 长度。
- 哈希。
- 脱敏后的前后缀。
文件路径也可能包含用户名、项目名称或内部目录信息,应根据实际安全要求决定是否脱敏。
安全说明
API 集成时建议遵循以下原则:
- Access Secret 不应保存到前端代码。
- 不应将 Access Secret 提交到 Git 仓库。
- 不要在普通日志中记录完整 Authorization Header。
- 不要记录完整 Access Secret。
- 对
digest和signature进行必要的日志脱敏。 - 通过 HTTPS 调用远程签名服务。
- 客户端应验证 HTTP 状态和业务状态。
- 为网络请求设置合理的超时和重试策略。
远程代码签名 API 返回的是签名结果,而不是私钥。
代码签名私钥始终保留在远程 HSM 中。
何时使用 API
如果现有集成方式已经满足需求,通常可以直接使用对应工具。
| 场景 | 推荐方式 |
|---|---|
| 直接签名 EXE、DLL、MSI 等文件 | 客户端工具 |
| Microsoft SignTool、Visual Studio 等 Windows 软件 | Windows Provider |
| JAR 文件签名 | Java 集成 |
| GitHub Actions、Electron Builder 等自动构建 | CI/CD 与构建工具 |
| 自行开发签名客户端 | API |
| 自行实现文件格式签名流程 | API |
| 需要直接控制摘要和签名结果 | API |
API 更适合需要控制底层签名流程的开发者。
如果只是需要对普通文件完成代码签名,优先使用已有客户端或标准 Provider 可以减少自行处理签名文件格式的工作量。