API Integration
sslTrus provides a remote code signing API for developers who need to build their own signing clients, build systems, or other signing integration programs.
The API receives a file digest computed by the client, and the remote code signing service uses the designated code signing certificate to complete the private key signing and returns the signing result.
The client is responsible for:
- Computing the digest of the data to be signed.
- Constructing the required signature structure for the target file.
- Calling the remote signing API.
- Writing the returned signing result into the target file or signature structure.
- Reporting the client's final processing result as needed.
The code signing private key is always stored in the cloud HSM and is never returned to the client via the API.
Access Endpoint
Default production endpoint:
https://ssl.face.racent.com
NICSRS environment:
https://ssl.face.nicsrs.com
Complete signature interface:
POST https://ssl.face.racent.com/v1/codesign/sign
Result reporting API:
POST https://ssl.face.racent.com/v1/codesign/report-sign
If the actual deployment environment uses a different service address, please refer to the address provided by the delivery or operations team.
Identity Authentication
The API uses HTTP Basic Auth.
Correspondence:
Username = Access Key
Password = Access Secret
Request headers:
Authorization: Basic <base64(accessKey:accessSecret)>
Here is the translated segment:
For example:
printf "%s:%s" "$ACCESS_KEY" "$ACCESS_SECRET" | base64
When actually using curl, you can provide it directly through the -u parameter:
curl -u "$ACCESS_KEY:$ACCESS_SECRET"
Access Secret is a sensitive credential and must not be written into source code, public configuration files, logs, or frontend pages.
General Request Format
For API usage:
HTTPS
POST
JSON
Request headers:
Content-Type: application/json
Accept: application/json
Authorization: Basic <credentials>
Universal Response Format
The API returns a unified JSON structure:
{
"code": 0,
"message": "ok",
"data": {}
}
Field description:
| Field | Type | Description |
|---|---|---|
code | integer | Business status code, 0 indicates success |
message | string | Status or error message |
data | object | API business data |
The client needs to check both the HTTP status code and the business status code.
It is recommended to handle it as follows:
HTTP 非 2xx
↓
HTTP 请求失败
HTTP 2xx + code != 0
↓
业务失败
HTTP 2xx + code == 0
↓
读取 data
Don't judge the success of a signed request solely based on HTTP 200.
Signature API
Endpoint:
POST /v1/codesign/sign
This interface is used to submit the digest to be signed and obtain the remote private key signing result.
Request Parameters
Request example:
{
"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
}
}
Main parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
code | string | Yes | Code signing certificate number |
digest | string | Yes | Base64 encoding of the original bytes of the digest to be signed |
algorithm | string | Yes | Digest algorithm |
padding | string | Yes | RSA padding mode, currently fixed to PKCS1 |
extra | object | No | Client context and audit information |
Digest algorithm
Currently supported:
SHA1
SHA256
For example, when using SHA-256:
{
"algorithm": "SHA256"
}
algorithm must be consistent with the digest algorithm actually used by digest.
digest format
digest must be:
Hash raw bytes → Base64
Not:
文件内容 Base64
Neither is it:
十六进制哈希字符串
For example, if a SHA-256 digest itself is 32 bytes, you should Base64-encode these 32 raw bytes before passing them to the interface.
padding
Currently fixed to use:
PKCS1
That is:
{
"padding": "PKCS1"
}
Do not pass in any other padding method.
extra
extra is used to record client context, audit information, and assist with troubleshooting.
Supported fields:
| Field | Type | Description |
|---|---|---|
platform | string | Client platform |
version | string | Client version |
revision | string | Client build revision |
time | string | Build time or request-side recording time |
hostname | string | Hostname of the requesting host |
signing_filename | string | Signed file name or local path |
signing_filesize | integer | File size, in bytes |
For example:
{
"extra": {
"platform": "linux/amd64",
"version": "1.2.0",
"hostname": "github-runner-01",
"signing_filename": "app.exe",
"signing_filesize": 5242880
}
}
If signing_filename contains internal directories, usernames, or other sensitive information, it is recommended to redact it according to the customer-side security policy.
Example of signed request
Use 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
Signature Response
Successful response:
{
"code": 0,
"message": "ok",
"data": {
"id": "735985894427246592",
"signature": "BASE64_ENCODED_SIGNATURE"
}
}
Return fields:
| Field | Type | Description |
|---|---|---|
id | string | Signature record ID |
signature | string | Base64 encoding of the RSA signature result |
For actual signing capabilities, the client primarily uses:
data.signature
If the final status needs to be reported after local processing is completed, the following must also be saved:
data.id
Client Processing Flow
Typical flow:
读取待签名文件
↓
按照目标格式生成待签名数据
↓
计算摘要
↓
Base64 编码摘要
↓
POST /v1/codesign/sign
↓
获得 signature
↓
构造最终签名结构
↓
写回目标文件
↓
POST /v1/codesign/report-sign
Note that:
/v1/codesign/sign
Only responsible for the underlying remote private key signing.
How PE Authenticode, JAR, PDF, or other file formats organize the signing structure is handled by the client according to the target format.
Reporting the signing result
API:
POST /v1/codesign/report-sign
After the client receives the remote signing result, failures may still occur in subsequent processes, for example:
- Failure to construct the final signature structure.
- Failure to write to the target file.
- Local file permission errors.
- Exceptions in subsequent client processing.
You can use this API to send the final processing status back to the server.
Request parameters
{
"id": "735985894427246592",
"status": 1
}
Parameters:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The signature record ID returned by /v1/codesign/sign |
status | integer | Yes | The client's final processing status |
Status values:
| Status | Description |
|---|---|
1 | The client's final processing succeeded |
2 | The client's final processing failed |
Request example
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
Successful Response
{
"code": 0,
"message": "ok",
"data": null
}
Signature Count
The API signature count is based on whether the remote signing operation is successful.
HTTP 2xx
code == 0
data.signature 非空
At the same time, both of the following conditions are met, it is considered a successful signature:
签名次数 +1
The following situations do not consume signature quota:
- Authentication failure.
- Parameter error.
- Network request failure.
- Business request failure.
- The server did not successfully return the signed content.
Special attention is required:
/v1/codesign/report-sign
This is only for reporting the client's final processing status and does not constitute a new signing operation, nor will it increase or decrease the signing count.
Even if the client successfully obtains the remote signing result, if it subsequently fails to write the file locally, the previously completed remote private key signing still counts as one signing occurrence.
For more details on signing count rules, refer to Reference.
Error Handling
The client should handle separately:
- Network errors.
- HTTP errors.
- API business errors.
- Client-side local processing errors.
Authentication Failure
For example:
{
"code": 401,
"message": "unauthorized",
"data": null
}
Should check:
- Whether the Access Key is correct.
- Whether the Access Secret is correct.
- Whether the request correctly carries the Authorization Header.
Parameter Error
For example:
{
"code": 400,
"message": "invalid request",
"data": null
}
Key points to check:
- Whether
codeis correct. - Whether
digestis valid Base64. - Whether
algorithmmatches the digest. - Whether
paddingisPKCS1.
The client should not rely on fixed:
message
String execution program logic.
Business processing should prioritize the status code and the API contract.
Timeout and Retry
When calling the remote signing API, you should set a reasonable network timeout.
When a retry is needed, special attention should be paid to the following:
签名接口不是普通查询接口
If the client does not receive a response due to a network anomaly, it does not necessarily mean that the server has not completed the signing.
Therefore, when designing an automatic retry mechanism, you should avoid unlimited or unconditional repeated signing requests.
It is recommended to record the following separately:
- Request start time.
- Target certificate ID.
- Digest identifier.
- HTTP status.
- Business status code.
- Returned signing record ID.
- Client final processing status.
Do not log the full Access Secret.
Logging and Auditing
It is recommended to record necessary signing context, for example:
certificate code
platform
client version
hostname
filename
filesize
sign record id
result
For:
digest
signature
For data of this size, it is not recommended to write it completely into ordinary logs.
You can record:
- Length.
- Hash.
- Desensitized prefix and suffix.
File paths may also contain usernames, project names, or internal directory information. Decide whether to desensitize them based on actual security requirements.
Security Notes
When integrating with the API, it is recommended to follow these principles:
- Access Secret should not be saved in frontend code.
- Access Secret should not be committed to a Git repository.
- Do not record the complete Authorization Header in ordinary logs.
- Do not log the complete Access Secret.
- Apply necessary log desensitization to
digestandsignature. - Call the remote signing service over HTTPS.
- The client should verify both the HTTP status and the business status.
- Set reasonable timeout and retry policies for network requests.
The remote code signing API returns the signing result, not the private key.
The code signing private key always remains in the remote HSM.
When to Use the API
If your existing integration method already meets your needs, you can usually use the corresponding tool directly.
| Scenario | Recommended Approach |
|---|---|
| Directly signing files such as EXE, DLL, MSI | Client Tool |
| Windows software like Microsoft SignTool, Visual Studio | Windows Provider |
| JAR file signing | Java Integration |
| Automated builds with GitHub Actions, Electron Builder | CI/CD and Build Tools |
| Developing your own signing client | API |
| Implementing your own file format signing process | API |
| Need direct control over the digest and signing result | API |
The API is more suitable for developers who need to control the underlying signing process.
If you only need to complete code signing for regular files, using existing clients or standard Providers first can reduce the workload of handling signing file formats yourself.