Интеграция 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 | Ревизия сборки клиента |
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 | Идентификатор записи подписи |
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 |
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 в запросе.
Ошибка параметра
Например:
{
"code": 400,
"message": "invalid request",
"data": null
}
Следует обратить особое внимание на проверку:
- Правильность
code. - Является ли
digestкорректным Base64. - Соответствует ли
algorithmсводке. - Является ли
paddingPKCS1.
Клиент не должен полагаться на фиксированные:
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 и другое программное обеспечение Windows | Windows Provider |
| Подпись файлов JAR | Интеграция с Java |
| Автоматическая сборка в GitHub Actions, Electron Builder и т. д. | CI/CD и инструменты сборки |
| Самостоятельная разработка клиента подписи | API |
| Самостоятельная реализация процесса подписи файлового формата | API |
| Необходимость напрямую управлять дайджестом и результатом подписи | API |
API больше подходит разработчикам, которым требуется контролировать низкоуровневый процесс подписи.
Если нужно только выполнить подпись кода для обычных файлов, предпочтительно использовать существующий клиент или стандартный Provider: это позволяет сократить объём работы по самостоятельной обработке формата подписываемых файлов.