跳到主要内容
版本:V2.2.1

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": {}
}

字段说明:

字段类型说明
codeinteger业务状态码,0 表示成功
messagestring状态或错误信息
dataobject接口业务数据

客户端需要同时判断 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
}
}

主要参数:

参数类型必填说明
codestring代码签名证书编号
digeststring待签名摘要原始字节的 Base64 编码
algorithmstring摘要算法
paddingstringRSA 填充方式,当前固定为 PKCS1
extraobject客户端上下文和审计信息

摘要算法

当前支持:

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 用于记录客户端上下文、审计信息以及辅助问题排查。

支持:

字段类型说明
platformstring客户端平台
versionstring客户端版本
revisionstring客户端构建 revision
timestring构建时间或请求侧记录时间
hostnamestring发起请求的主机名
signing_filenamestring被签名文件名或本地路径
signing_filesizeinteger文件大小,单位为字节

例如:

{
"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"
}
}

返回字段:

字段类型说明
idstring签名记录 ID
signaturestringRSA 签名结果的 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
}

参数:

字段类型必填说明
idstring/v1/codesign/sign 返回的签名记录 ID
statusinteger客户端最终处理状态

状态值:

状态说明
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

只是上报客户端最终处理状态,不属于新的签名操作,也不会增加或减少签名次数。

即使客户端已经成功获得远程签名结果,但随后在本地写入文件时失败,之前成功完成的远程私钥签名仍然已经产生一次签名次数。

更多计次规则请参阅 参考资料

错误处理

客户端应分别处理:

  1. 网络错误。
  2. HTTP 错误。
  3. API 业务错误。
  4. 客户端本地处理错误。

鉴权失败

例如:

{
"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。
  • digestsignature 进行必要的日志脱敏。
  • 通过 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 可以减少自行处理签名文件格式的工作量。