Перейти к основному содержимому

Интеграция 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ДаАлгоритм дайджеста
paddingstringДаСпособ заполнения RSA, в настоящее время фиксировано как 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Ревизия сборки клиента
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Идентификатор записи подписи
signaturestringРезультат 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
}

Параметры:

ПолеТипОбязательноеОписание
idstringДаИдентификатор записи подписи, возвращённый /v1/codesign/sign
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 в запросе.

Ошибка параметра

Например:

{
"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.
  • Не записывайте полный заголовок Authorization Header в обычные журналы.
  • Не записывайте полный Access Secret.
  • Выполняйте необходимое маскирование в журналах для digest и signature.
  • Вызывайте удалённый сервис подписи через HTTPS.
  • Клиент должен проверять HTTP-статус и бизнес-статус.
  • Настройте разумные тайм-ауты и политику повторных попыток для сетевых запросов.

API удалённой подписи кода возвращает результат подписи, а не закрытый ключ.

Закрытый ключ подписи кода всегда остаётся в удалённом HSM.

Когда использовать API

Если существующий способ интеграции уже удовлетворяет требованиям, обычно можно напрямую использовать соответствующий инструмент.

СценарийРекомендуемый способ
Прямая подпись файлов EXE, DLL, MSI и т. д.Клиентский инструмент
Microsoft SignTool, Visual Studio и другое программное обеспечение WindowsWindows Provider
Подпись файлов JARИнтеграция с Java
Автоматическая сборка в GitHub Actions, Electron Builder и т. д.CI/CD и инструменты сборки
Самостоятельная разработка клиента подписиAPI
Самостоятельная реализация процесса подписи файлового форматаAPI
Необходимость напрямую управлять дайджестом и результатом подписиAPI

API больше подходит разработчикам, которым требуется контролировать низкоуровневый процесс подписи.

Если нужно только выполнить подпись кода для обычных файлов, предпочтительно использовать существующий клиент или стандартный Provider: это позволяет сократить объём работы по самостоятельной обработке формата подписываемых файлов.