CleanSign API
REST-API сервиса CleanSign для проверки электронных подписей (ЭП/ЭЦП). Принимает документы и файлы подписи через multipart/form-data, возвращает JSON со сведениями о подписантах, цепочкой сертификатов и классификацией подписи. Использует тот же движок проверки, что и веб-форма на главной странице. Подходит для пакетной обработки документов и мониторинга срока действия сертификатов; готовых коннекторов к учётным системам и операторам ЭДО сервис не поставляет — встраивание выполняется на стороне клиента.
https://api.cleanvoice.ru/cleansign/api/v1.
Какие проверки выполняются
- Соответствие хеша документа подписанному атрибуту
messageDigest— отсекает подмену подписанного содержимого. - Криптографическая проверка подписи (ГОСТ Р 34.10-2012, RSA, ECDSA).
- Построение цепочки сертификатов до закреплённого trust-anchor (ГУЦ Минцифры) в режиме fail-closed.
- Проверка привязки
signingCertificateV2(RFC 5126), исключающая подмену сертификата подписанта. - Проверка аккредитации УЦ-эмитента в реестре Минцифры на текущий момент и на момент подписания.
- Опционально: проверки OCSP и CRL, верификация контр-подписей и меток времени CAdES (профили BES — A).
- Классификация подписи по 63-ФЗ — КЭП (она же УКЭП — усиленная квалифицированная), НЭП (усиленная неквалифицированная) или иная — с указанием класса средства ЭП (КС1, КС2, КС3) и СКЗИ.
Поддерживаемые форматы
- CMS / PKCS#7 — отделённая подпись в виде самостоятельного файла рядом с документом. Расширения:
.sig,.sgn,.sign,.p7s,.bin(плюс числовые суффиксы вида.sig2,.sig.001). Подпись принимается в форматах raw DER, base64 и PEM — обёртка определяется автоматически. Кроме того, если файл имеет нестандартное расширение (например, оператор переименовал.sigв.txtили вставил base64 подписи в текстовый файл) и его размер не превышает 256 KB, сервис проверяет содержимое и распознаёт CMS по сигнатуреsignedData— после этого файл встаёт в пайплайн как обычная подпись. Документом может быть любой файл —.pdf,.docx,.xlsx,.doc,.xml,.txt,.html,.rtfи любой бинарный. - CAdES — те же расширения, что и CMS; распознаются профили BES, EPES, T, C, X-L Type 1, A. Штампы времени RFC 3161 проверяются end-to-end (TSA-подпись + сравнение imprint), для CAdES-A реконструируется imprint archive-timestamp v2.
- PAdES — встроенная подпись в PDF (
.pdf): чтение/ByteRange,/Contents, поддержка нескольких подписей в одном документе и словаря/DSS(DSS dictionary). - Opaque CMS — «совмещённая» подпись: PKCS#7
signedData, в котором подписываемый документ зашит внутри (encapContentInfo.eContent, RFC 5652 §5.2). Такой формат выдаёт Госключ при подписании PDF: файл может быть названdoc.pdf, но его байты — это CMS-обёртка, а сам PDF лежит внутри контейнера. Сервис автоматически распознаёт opaque CMS у любого расширения, извлекает встроенный документ и верифицирует подпись против него (отдельный файл-документ не требуется). В отчёте «имя файла подписи» получает синтетическое значение«{name} (opaque CMS)», а «имя файла документа» — фактическое имя загруженного файла. - S/MIME — почтовые сообщения
multipart/signedи opaqueapplication/pkcs7-mime. Расширения:.eml,.p7m,.mime,.msg. - XMLDSig / XAdES — XML-файлы (
.xml) с алгоритмами ГОСТ Р 34.10-2001/2012 (256/512) или RSA/ECDSA. Поддерживаются преобразованияc14n,exc-c14n,enveloped-signature,base64, W3C-1999 XPath и W3C-2002 XPath-Filter 2, а также проприетарныеurn://smev-gov-ru/xmldsig/transform(СМЭВ-3) иurn:xml-dsig:transformation:v1.1(ФТС таможня — частично, для мульти-namespace субдеревьев см. Известные ограничения в общей документации). Принимаются обе URI-семьи алгоритмов:urn:ietf:params:xml:ns:cpxmlsec:algorithms:*(CryptoPro xmlsec) иhttp://www.w3.org/2001/04/xmldsig-more#*(RFC 4490). - OOXML —
.docx,.xlsx,.pptxс поддержкойRelationshipTransformпо ECMA-376 п.13. - ZIP-архивы —
.zipраспаковывается на один уровень: документы и подписи внутри сопоставляются по содержимому (хеш) и по имени. Также поддерживается «архив подписан целиком»:foo.zip+foo.zip.sigлибоarchive.zipс сиблингом.sig, чейmessageDigestсовпадает с хешем архива.
Версионирование
Канонические пути API располагаются под префиксом /api/v{N}/. Контракт v1 зафиксирован: в существующие ответы могут добавляться новые необязательные поля, но имена и типы существующих полей не изменяются и не удаляются. Несовместимое изменение (переименование поля, изменение типа, удаление секции ответа) выпускается параллельной версией /api/v2; /api/v1 продолжает работать в прежнем виде.
Незаверсионированные пути /api/verify и /api/cert/check — это псевдонимы, ведущие на текущую актуальную версию. Они сохраняются для обратной совместимости со старыми интеграциями. В новых интеграциях используйте только версионированные пути, чтобы зафиксировать контракт.
Аутентификация
Доступ к API авторизуется по токену. Токен выдаётся при подключении и передаётся в заголовке Authorization: Bearer <token>. Запросы без валидного токена отклоняются с кодом 401 Unauthorized.
Все запросы выполняются по HTTPS. Максимальный размер тела запроса — 200 МБ.
Коды ошибок
| HTTP | Когда | Что вернётся |
|---|---|---|
| 200 OK | Запрос обработан. Невалидная подпись — это штатный результат проверки, статус по каждому файлу возвращается в items[i].status. | JSON: VerificationResponse или CertificateCheckResponse |
| 400 Bad Request | Запрос не в формате multipart/form-data, отсутствует поле с файлами или повреждена форма. | { "error": "..." } |
| 413 Payload Too Large | Превышен один из лимитов: размер запроса, размер записи в архиве, число записей, коэффициент сжатия (защита от zip-bomb). | { "error": "..." } с указанием конкретного лимита |
| 500 Internal Server Error | Внутренняя ошибка сервиса. | { "error": "..." } |
items[i].isValid и items[i].status.POST /api/v1/verify
Проверяет одну или несколько связок «документ + подпись». Принимает ZIP-архивы (распаковываются рекурсивно), пары вида «doc.pdf + doc.pdf.sig», PDF со встроенной PAdES-подписью, opaque-CMS файлы (документ зашит в encapContentInfo — типичный выхлоп Госключа), .eml с S/MIME, файлы .docx, .xlsx, .pptx и .xml (XMLDSig).
Про revocation в ответе. CRL-проверка делается поиском в CRL-банке в памяти — никаких сетевых запросов в момент проверки. Если CDP-URL сертификата ещё не проиндексирован банком (первая встреча УЦ), проверка revocation-crl приходит со статусом Skipped и пометкой «CRL not yet indexed»; URL автоматически кладётся в очередь фоновой прокачки, следующая проверка отдаст Good/Revoked. OCSP по умолчанию асинхронный: revocation-ocsp приходит как Pending, клиент обращается к /api/v1/revocation и подменяет результат. OCSP сразу в ответе — флаг ?withRevocation=true (медленнее на 0.5–10 с).
Параметры запроса (query или поле формы)
| Поле | Тип | Описание |
|---|---|---|
| files | file[] | Один или несколько файлов. Документ и подпись могут передаваться отдельными частями формы либо одним ZIP-архивом. Имя поля формы — files. |
| returnSignatureFile | bool | Если true, в каждый элемент результата добавляется signatureFileBase64 — байты файла подписи в base64 (для отделённой подписи), внутренний CMS (для PAdES, S/MIME и opaque CMS — здесь это байты самого загруженного файла) либо файл sig*.xml (для OOXML). Значение по умолчанию — false. |
| returnCertificateFile | bool | Если true, в каждом подписанте возвращается поле certificateBase64 с DER-представлением сертификата подписанта в base64. Значение по умолчанию — false. |
Пример запроса
curl -X POST 'https://api.cleanvoice.ru/cleansign/api/v1/verify?returnCertificateFile=true' \
-F 'files=@invoice.pdf' \
-F 'files=@invoice.pdf.sig' \
-H 'Authorization: Bearer YOUR_KEY'
import requests
files = [
('files', ('invoice.pdf', open('invoice.pdf', 'rb'))),
('files', ('invoice.pdf.sig', open('invoice.pdf.sig', 'rb'))),
]
resp = requests.post(
'https://api.cleanvoice.ru/cleansign/api/v1/verify',
params={'returnCertificateFile': 'true'},
files=files,
headers={'Authorization': 'Bearer YOUR_KEY'},
)
data = resp.json()
print(data['summary']['validlySigned'], 'valid of', data['summary']['totalDocuments'])
const fd = new FormData();
fd.append('files', pdfFile, 'invoice.pdf');
fd.append('files', sigFile, 'invoice.pdf.sig');
const r = await fetch('https://api.cleanvoice.ru/cleansign/api/v1/verify?returnCertificateFile=true', {
method: 'POST',
body: fd,
});
const data = await r.json();
console.log(data.summary.validlySigned + ' / ' + data.summary.totalDocuments);
using var http = new HttpClient { BaseAddress = new Uri("https://api.cleanvoice.ru/cleansign/") };
http.DefaultRequestHeaders.Authorization = new("Bearer", "YOUR_KEY");
using var form = new MultipartFormDataContent();
form.Add(new ByteArrayContent(File.ReadAllBytes("invoice.pdf")), "files", "invoice.pdf");
form.Add(new ByteArrayContent(File.ReadAllBytes("invoice.pdf.sig")), "files", "invoice.pdf.sig");
var resp = await http.PostAsync("api/v1/verify?returnCertificateFile=true", form);
var json = await resp.Content.ReadAsStringAsync();
Пример ответа (200 OK)
{
"summary": {
"totalDocuments": 1,
"signed": 1,
"validlySigned": 1,
"invalidSignatures": 0,
"notSigned": 0,
"orphanSignatures": 0
},
"items": [
{
"documentFile": "invoice.pdf",
"documentSize": 182734,
"signatureFile": "invoice.pdf.sig",
"isSigned": true,
"isValid": true,
"status": "Valid",
"documentHashAlgorithm": "GOST R 34.11-2012 (256)",
"documentHashHex": "8E5C…",
"messageDigestMatches": true,
"isPowerOfAttorney": false,
"signers": [
{
"subjectCommonName": "Иванов Иван Иванович",
"subjectType": "ЮЛ",
"signerShortName": "Иванов И. И.",
"signingTime": "2026-04-30T17:42:11+00:00",
"signatureValid": true,
"trustStatus": "Trusted",
"chainTrusted": true,
"trustedRootSubject": "CN=Минцифры России",
"classification": { "kind": "КЭП", "kindFull": "Квалифицированная электронная подпись",
"classes": ["КС1"], "subjectSignTool": "КриптоПро CSP (5.0.12000)",
"usesGost": true, "issuedByAccreditedUc": true, "isGoskey": false,
"deprecationWarnings": [] },
"attributes": { "inn": "772372861423", "innLe": "7709000010",
"ogrn": "1047709098315", "snils": "14233464635",
"email": "i.ivanov@example.com",
"givenName": "Иван Иванович", "surname": "Иванов",
"organization": "ООО «Пример»" },
"accreditation": { "issuingUcSki": "23F0DA4A5DE30C96E91F976A3E641689A1F8553C",
"issuingUcName": "УЦ ФНС России",
"accreditedFrom": "2024-01-01T00:00:00+00:00",
"accreditedTo": null },
// null accreditedTo → УЦ accredited at the moment of the response.
// null issuingUcSki → issuing УЦ wasn't found in the Минцифры registry.
// Clients derive "accredited at signing time" by comparing
// signingTime against AccreditedFrom / AccreditedTo themselves.
"certificateBase64": "MIIH…" // только если returnCertificateFile=true
}
],
"errors": [],
"warnings": []
}
]
}
POST /api/v1/cert/check
Проверка только сертификата, без документа. Эндпоинт оптимизирован для регулярных запусков из cron. Принимает .cer, .crt, .pem, .der или CMS-файл (.sig); во втором случае сертификат подписанта извлекается по SignerID. Возвращает срок действия, число дней до истечения, аккредитацию УЦ, статус OCSP и CRL, классификацию.
Пример: ежедневный мониторинг
#!/bin/bash
# Завершиться с ошибкой, если до истечения сертификата осталось менее 30 дней.
RESP=$(curl -sf -F files=@/etc/ssl/edo.cer https://api.cleanvoice.ru/cleansign/api/v1/cert/check)
DAYS=$(echo "$RESP" | jq '.items[0].daysUntilExpiry')
[ "$DAYS" -lt 30 ] && echo "ALERT: cert expires in $DAYS days" && exit 1
Пример ответа
{
"summary": { "total": 1, "currentlyValid": 1, "expiringSoon": 0, "expired": 0,
"trusted": 1, "untrusted": 0, "revoked": 0 },
"items": [{
"fileName": "edo.cer",
"source": "X509",
"subjectCommonName": "ООО «Пример»",
"issuer": "CN=Удостоверяющий центр Федерального казначейства",
"notBefore": "2025-08-12T08:14:00+00:00",
"notAfter": "2026-08-12T08:14:00+00:00",
"isCurrentlyValid": true,
"daysUntilExpiry": 97,
"publicKeyAlgorithm":"GOST R 34.10-2012 (256)",
"classification": { "kind": "КЭП", "classes": ["КС1"], "issuedByAccreditedUc": true },
"trust": { "status": "Trusted", "trusted": true,
"rootSubject": "CN=Минцифры России",
"chain": [...] },
"accreditation": { "issuingUcSki": "...", "issuingUcName": "УЦ Казначейства",
"accreditedFrom": "2024-01-01T00:00:00+00:00", "accreditedTo": null },
"revocation": null,
"revocationCrl": null
}]
}
Асинхронная OCSP-проверка сертификата
Эндпоинт делает OCSP-запрос к responder'у УЦ (RFC 6960) для одного сертификата. Спроектирован как асинхронное продолжение /api/v1/verify и /api/v1/cert/check: по умолчанию они откладывают OCSP-запрос (он может занять до нескольких секунд) и возвращают check со статусом Pending и URL OCSP-endpoint'а. Клиент (фронт или CLI) дёргает этот эндпоинт с DER-сертификатом подписанта и получает финальный статус.
CRL revocation через этот эндпоинт не запрашивается. Начиная с версии с CRL-банком, CRL-проверка делается сразу в ответе /verify и /cert/check по индексу отозванных серийников в памяти (см. /api/v1/crl-bank/stats) — это поиск за константное время без обращений по сети. Здесь только OCSP, который остаётся онлайн-запросом к серверу УЦ.
Сертификат-издатель резолвится из TrustStore по SubjectKeyIdentifier / IssuerDN. Если издателя нет в trust-store (зарубежные / тестовые УЦ — EJBCA, Let's Encrypt, DigiCert), check возвращается как NotApplicable с пометкой «issuer cert not in trust store» — без открытого ключа издателя OCSP-запрос построить нельзя.
Без rate-limit: UI стреляет в этот эндпоинт параллельно для каждого подписанта в multi-signer документе. Bearer-токен остаётся обязательным.
Запрос
POST /api/v1/revocation
Content-Type: application/json
Authorization: Bearer <session-token>
{
"signerCertBase64": "MIIH..."
}
Параметры тела
| Поле | Тип | Описание |
|---|---|---|
| signerCertBase64 | string | DER-сертификат подписанта в base64. Обычно копируется из ответа /verify — поле items[].signers[].certificateBase64. PEM-обёртку и пробелы убирать не нужно — парсер их игнорирует. |
Ответ — OCSP прошёл
200 OK
{
"ocsp": {
"status": "Good",
"producedAt": "2026-05-16T19:49:55+00:00",
"thisUpdate": "2026-05-16T19:49:55+00:00",
"ocspUrl": "http://ocsp1.taxcom.ru/OCSPAL/ocsp.srf"
},
"ocspCheck": {
"id": "revocation-ocsp",
"status": "Ok",
"details": "Endpoint: http://ocsp1.taxcom.ru/..."
}
}
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
| ocsp | OcspResult? | Сырой результат OCSP-запроса (RFC 6960). null если OCSP отключён в конфиге или не было issuer cert. |
| ocsp.status | string | Good / Revoked / Unknown / NoEndpoint / FetchFailed / InvalidResponse. Это сырое значение по протоколу OCSP (не унифицированный VerificationCheck.Status). |
| ocsp.ocspUrl | string? | URL, по которому был отправлен OCSP-запрос (из id-ad-ocsp AIA-extension сертификата). |
| ocspCheck | VerificationCheck | Унифицированный check той же формы, что в /verify. Содержит id="revocation-ocsp", status из таксономии VerificationCheck (Ok / Failed / Unreachable / NotApplicable / Skipped), endpoint URL в details. Подходит для прямой замены Pending-чека из /verify по id. |
Ответ — сертификат отозван
200 OK
{
"ocsp": {
"status": "Revoked",
"revocationTime": "2025-08-12T11:14:00+00:00",
"revocationReason": "keyCompromise",
"ocspUrl": "http://pki.tax.gov.ru/ocsp02/ocsp.srf"
},
"ocspCheck": {
"id": "revocation-ocsp",
"status": "Failed",
"critical": true,
"details": "Revoked at 2025-08-12T11:14:00Z, reason: keyCompromise. Endpoint: http://pki.tax.gov.ru/..."
}
}
Ответ — issuer не в trust-store (зарубежный/тестовый УЦ)
200 OK
{
"ocsp": null,
"ocspCheck": {
"id": "revocation-ocsp",
"status": "NotApplicable",
"details": "Cannot check OCSP: the signer's issuer certificate is not in the trust store..."
}
}
Для зарубежных УЦ (EJBCA, Let's Encrypt, DigiCert и т.п.) — это ожидаемый ответ. Чтобы OCSP заработал, добавьте сертификат-издатель в trust-store/intermediates/.
Ответ — OCSP выключен в конфиге
200 OK
{
"ocsp": null,
"ocspCheck": {
"id": "revocation-ocsp",
"status": "Skipped",
"details": "Disabled in configuration (CleanSign:TrustStore:EnableOcsp=false)."
}
}
Использование из браузера
// Достали cert из ответа /verify
const cert = response.items[0].signers[0].certificateBase64;
// Дёрнули revocation
const r = await fetch('/api/v1/revocation', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + token,
'Content-Type': 'application/json',
},
body: JSON.stringify({ signerCertBase64: cert }),
});
const { ocspCheck } = await r.json();
// Заменили Pending-чек на финальный
signer.checks = signer.checks.map(c =>
c.id === ocspCheck.id ? ocspCheck : c);
Inline-альтернатива для бизнес-API
Если асинхронная схема неудобна (например, скрипт по расписанию) — можно попросить /verify вернуть OCSP сразу в ответе:
POST /api/v1/verify?withRevocation=true
Content-Type: multipart/form-data
...
То же для /api/v1/cert/check?withRevocation=true. В этом режиме отдельный вызов /revocation не нужен, но первый ответ возвращается на 0.5–10 секунд медленнее (зависит от скорости responder'а УЦ). CRL в любом случае проверяется inline через CRL-банк.
Список аккредитованных УЦ
Возвращает текущий снимок реестра аккредитованных удостоверяющих центров Минцифры из памяти. Источник — TSL-XML по адресу https://e-trust.gosuslugi.ru/CA/DownloadTSL?schemaVersion=0, сохраняется в trust-store/registry/tsl-cache.xml и обновляется фоновой задачей каждые 24 часа. На «свежем» хосте — ~481 УЦ.
Эндпоинт открыт (без сессии и rate-limit), читает только из памяти — подходит для регулярных опросов из мониторинга или интеграций.
Параметры
Нет.
Ответ
200 OK
{
"loadedAt": "2026-05-13T01:44:04.5976972Z",
"source": "tsl-cache.xml",
"count": 481,
"items": [
{
"subjectKeyIdentifier": "23F0DA4A5DE30C96E91F976A3E641689A1F8553C",
"name": "УЦ ФНС России",
"inn": "7707329152",
"ogrn": "1047707030513",
"accreditedFrom": "2021-12-29T00:00:00",
"accreditedTo": null,
"notes": "Действует"
},
...
]
}
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
| loadedAt | datetime | Когда снимок был загружен в память (соответствует времени изменения файла tsl-cache.xml или generatedAt из встроенного снимка). |
| source | string | Источник: tsl-cache.xml при живом TSL или accredited-ucs.json (bundled) на самом cold-start. |
| count | int | Количество УЦ в реестре. |
| items[].subjectKeyIdentifier | string | Hex SKI сертификата УЦ — стабильный идентификатор (Subject DN и ОГРН/ИНН могут переоформляться). |
| items[].name | string | Название УЦ. |
| items[].inn | string? | ИНН организации УЦ. |
| items[].ogrn | string? | ОГРН организации УЦ. |
| items[].accreditedFrom | datetime? | Когда была получена аккредитация. |
| items[].accreditedTo | datetime? | Когда аккредитация была отозвана. null = действует на текущий момент. |
| items[].notes | string? | Текстовая пометка из TSL (Действует / Прекращена / Аннулирована / Приостановлена). |
Поиск УЦ по SKI
Возвращает запись о конкретном УЦ по hex-значению SubjectKeyIdentifier. SKI можно получить из leaf-сертификата подписанта — он совпадает с SKI его эмитента, либо из ответа /verify (accreditation.issuingUcSki).
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
| ski | string | Hex SubjectKeyIdentifier (без разделителей, регистр любой). |
Ответ
200 OK — объект AccreditedUc (поля как в items[] выше).
404 Not Found — УЦ с таким SKI в реестре нет.
Поиск отозванных сертификатов по серийному номеру
Поиск серийника в банке CRL в памяти — фоновая служба раз в сутки выкачивает Certificate Revocation List каждого аккредитованного УЦ из TSL Минцифры и держит в памяти индекс отозванных серийников. Этот эндпоинт ищет hex-серийник по всем CRL, которые сейчас в банке.
Применение: антифрод, сторонний мониторинг конкретного сертификата без перезаливки файла, аудит выпущенных сертификатов.
Важно: пустой результат означает «не найден в покрытых банком УЦ» — это не то же самое, что «гарантированно не отозван». Источник списка URL — <АдресаСписковОтзыва> в TSL Минцифры, поэтому покрываются все 481 аккредитованных УЦ. Сертификаты неаккредитованных или зарубежных издателей в банке отсутствуют.
Авторизация
Bearer-токен сессии. Rate-limit slot не тратится — подходит для регулярных опросов.
Параметры пути
| Параметр | Тип | Описание |
|---|---|---|
| serial | string | Hex-серийник сертификата. Принимаются форматы: aabbcc, 0xaabbcc, aa:bb:cc. Регистр любой, пробелы/дефисы игнорируются. |
Ответ
200 OK
{
"serialHex": "23f0da4a5de30c96e91f976a3e641689a1f8553c",
"bankSize": 17,
"lastRefreshedAt": "2026-05-17T01:42:11.319Z",
"hits": [
{
"url": "http://pki.tax.gov.ru/cdp/...crl",
"issuerDn": "C=RU, O=ФНС России, ...",
"issuerAkiHex": "23f0da4a5de30c96e91f976a3e641689a1f8553c",
"revocationDate": "2025-08-12T11:14:00Z",
"reason": "keyCompromise"
}
]
}
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
| serialHex | string | Серийник в каноничном виде (без префикса 0x, в нижнем регистре). |
| bankSize | int | Сколько CRL сейчас в банке. |
| lastRefreshedAt | datetime? | Когда фоновое обновление последний раз отработало. null до первого прогона. |
| hits[] | array | Совпадения. Обычно 0 или 1. >1 означает что разные УЦ переиспользовали серийник (патология). |
| hits[].url | string | CRL-URL где найден серийник. |
| hits[].issuerDn | string | Issuer DN из CRL — название УЦ, который отозвал. |
| hits[].issuerAkiHex | string? | AuthorityKeyIdentifier УЦ (hex). Стабильный идентификатор УЦ через смены DN. |
| hits[].revocationDate | datetime | Когда сертификат был отозван. |
| hits[].reason | string? | Причина из RFC 5280 §5.3.1: keyCompromise, cACompromise, affiliationChanged, superseded, cessationOfOperation, certificateHold, removeFromCRL, privilegeWithdrawn, aACompromise, unspecified. |
Состояние CRL-банка
Сведения о банке в памяти: сколько CRL покрыто, общее число проиндексированных отозванных записей, время последнего обновления. С параметром ?per=1 возвращает разбивку по каждому CRL (URL, issuer DN, окно thisUpdate / nextUpdate, число записей, флаг проверки подписи).
Как банк наполняется
Источник CDP-URL'ов — сам TSL Минцифры. В XML по адресу https://e-trust.gosuslugi.ru/CA/DownloadTSL?schemaVersion=0 для каждого аккредитованного УЦ перечислены теги <АдресаСписковОтзыва><Адрес>…</Адрес> — это полный авторитетный список (~3000 уникальных URL'ов по 481 УЦ, сопровождается Минцифры ежедневно). Никаких ручных списков и догадок по факту использования — только данные из TSL.
- На старте сервиса
MintsifryRegistryRefreshServiceчитает TSL изtrust-store/registry/tsl-cache.xml. Тут жеParseTslCrlUrlsизвлекает все CDP-URL'ы и добавляет вtrust-store/crl-bank/known-urls.json. Внутренние / VPN-only хосты (10.x.x.x, 192.168.x.x, *.local) отфильтрованы как недостижимые с публичного хоста. - Фоновая служба
CrlBankRefreshServiceзапускается раз в сутки в 03:00 МСК (00:00 UTC) — минимальная нагрузка на сервис, к началу рабочего дня в Москве (~09:00) банк уже полностью прокачан. Час и минута настраиваются:CleanSign:CrlBank:ScheduleUtcHour/ScheduleUtcMinute. - Если при запуске банк пустой (первый запуск либо удалили
trust-store/crl-bank/crls/) — служба запускает немедленный догоняющий прогон, не дожидаясь ночного слота. - На каждом прогоне служба проходит весь
known-urls.jsonс параллелизмомConcurrency(по умолчанию 8): для каждого URL делает HTTP GET, парсит BouncyCastle'ом, проверяет подпись CRL относительно trust-store, индексирует отозванные серийники вFrozenDictionary<BigInteger,RevokedEntry>, и пишет на диск:trust-store/crl-bank/crls/<sha256(url)>.crl— сырые DER-байты.trust-store/crl-bank/crls/<sha256(url)>.json— сопроводительные сведения: URL, issuerDn, AKI, thisUpdate/nextUpdate, signatureVerified, last_fetched.
- После прохождения всех URL делается атомарная замена снимка в памяти (потокобезопасное чтение без блокировок).
- На каждом обновлении TSL (раз в сутки) новые URL'ы из
<АдресаСписковОтзыва>добавляются вknown-urls.json. Старые URL'ы оттуда не удаляются — они остаются актуальными для сертификатов, которые были выпущены под старым ключом УЦ до его ротации. - При перезапуске сервиса конструктор
CrlBankсинхронно восстанавливает индексы с диска — не теряем покрытие в промежутке между ночными прогонами.
Что в памяти. На каждый CRL держим только то, что нужно для поиска: FrozenDictionary<BigInteger,RevokedEntry> отозванных серийников + thisUpdate/nextUpdate/signatureVerified. Сами «не отозванные» серийники не нужны — CRL по определению содержит только отозванные, остальное считается действительным в пределах окна.
Что на диске. Полный CRL DER + сопроводительные сведения JSON. При перезапуске всё восстанавливается без обращения по HTTP.
Покрытие. Полное по всем 481 аккредитованным УЦ Минцифры. Если в TSL появляется новый УЦ — его CRL прокачается на ближайшем ночном прогоне. УЦ, который не аккредитован (зарубежные тестовые EJBCA, Let's Encrypt и т.п.), банком не покрывается — что корректно по смыслу: 63-ФЗ обязывает доверять только аккредитованным УЦ.
Предельный размер CRL. Файл больше CleanSign:CrlBank:MaxCrlSizeBytes (по умолчанию 500 МБ) пропускается с предупреждением в журнале — защита от случайно опубликованного гигабайта.
Если CRL у УЦ не отвечает / 404. Старый CRL и его индекс в памяти и на диске остаются — следующая попытка через сутки. Покрытие не теряется из-за временного сбоя CDP.
Запаздывание отзыва. Сертификат, отозванный сразу после ночного прогона, попадёт в наш банк только на следующий день. Окно — до 24 ч. Для большинства задач это приемлемо (КриптоПро CSP по умолчанию делает то же самое).
Авторизация
Bearer-токен сессии. Rate-limit slot не тратится.
Параметры запроса
| Параметр | Тип | Описание |
|---|---|---|
| per | string? | Если 1 или true — включить разбивку perCrl[]. По умолчанию опускается, чтобы ответ оставался компактным. |
Ответ
200 OK
{
"totalCrls": 17,
"totalRevokedEntries": 1842153,
"lastRefreshedAt": "2026-05-17T01:42:11.319Z",
"perCrl": [
{
"url": "http://pki.tax.gov.ru/cdp/...crl",
"issuerDn": "C=RU, O=ФНС России, ...",
"thisUpdate": "2026-05-16T15:13:47Z",
"nextUpdate": "2026-05-17T15:13:47Z",
"revokedCount": 1240811,
"signatureVerified": true
},
...
]
}
Поля ответа
| Поле | Тип | Описание |
|---|---|---|
| totalCrls | int | Сколько разных CRL сейчас в банке. |
| totalRevokedEntries | long | Суммарное число проиндексированных отозванных серийников по всем CRL. |
| lastRefreshedAt | datetime? | UTC-время последнего успешного прогона обновления. |
| perCrl[] | array? | Возвращается только при ?per=1. |
| perCrl[].url | string | URL cRLDistributionPoint. |
| perCrl[].issuerDn | string | Issuer DN — УЦ который опубликовал CRL. |
| perCrl[].thisUpdate | datetime? | Время выпуска CRL по самой CRL. |
| perCrl[].nextUpdate | datetime? | Время следующего ожидаемого обновления. |
| perCrl[].revokedCount | int | Число отозванных серийников в этом CRL. |
| perCrl[].signatureVerified | bool | Проверена ли подпись CRL против корня из trust-store. Если false — содержимое в банке отображается, но revocation-ответы такого CRL в /verify не учитываются (CrlChecker делает fallback на live HTTP). |
VerificationResponse
Ответ POST /api/v1/verify.
| Поле | Тип | Описание |
|---|---|---|
| summary | object | Сводка по всему запросу. |
| summary.totalDocuments | int | Сколько документов было распознано. |
| summary.signed | int | Из них подписанных (любым статусом, включая невалидные). |
| summary.validlySigned | int | Из подписанных — прошедших полную проверку (status=Valid). |
| summary.invalidSignatures | int | Подписанных с фейлом (хэш не совпал, недоверенная цепочка, пр.). |
| summary.notSigned | int | Документов, для которых не нашлось подписи. |
| summary.orphanSignatures | int | Подписей без сопоставленного документа. |
| items | DocumentVerificationResult[] | Результат по каждому документу/паре. См. ниже. |
DocumentVerificationResult
| Поле | Тип | Описание |
|---|---|---|
| documentFile | string | Имя/путь документа (включая путь внутри архива, если это ZIP). |
| documentSize | long | Размер документа в байтах. |
| signatureFile | string? | Имя/путь файла подписи. null для NotSigned. Для встроенной подписи — синтетическое имя вроде doc.pdf (PAdES), doc.pdf (opaque CMS), msg.eml (S/MIME application/pkcs7-signature). |
| isSigned | bool | Найдена ли вообще какая-либо подпись. |
| isValid | bool | Прошла ли подпись все обязательные проверки. true ↔ status=Valid. |
| status | string | Один из:
Valid (все обязательные проверки прошли);
Untrusted (математика подписи корректна, но цепочка не доходит до корня в trust-store);
DocumentHashMismatch (хеш документа не совпадает с подписанным значением — документ изменён или приклеена не та подпись);
InvalidSignature (криптографическая проверка не прошла);
InvalidSignatureContainer / BrokenContainer (файл подписи не парсится как корректный CMS);
OrphanSignature (подпись без сопоставленного документа в загрузке — поле signers всё равно заполнено, см. ниже);
NotSigned (документ без сопоставленной подписи);
UnverifiedXmlSignature (формат XMLDSig распознан и сертификат подписанта извлечён, но криптографический бинд подписи к документу программно подтвердить не удалось — типично для ФТС таможни на urn:xml-dsig:transformation:v1.1; рекомендуется ручная сверка в стороннем сервисе). |
| documentHashAlgorithm | string? | Человекочитаемое имя алгоритма (например, «GOST R 34.11-2012 (256)»). |
| documentHashHex | string? | Hex-представление вычисленного хеша документа. |
| messageDigestMatches | bool? | Совпал ли хеш документа с подписанным атрибутом messageDigest. false = «приклеили чужую подпись». |
| isPowerOfAttorney | bool | Файл является МЧД (машиночитаемой доверенностью) — определяется по имени ON_EMCHD_*.xml. |
| companionOfSignedFile | string? | Заполняется, когда сам файл не подписан, но в той же загрузке есть подписанный .xml / .json с тем же базовым именем — типовая схема российских госпорталов (СФР, ФНС, Госуслуги, Росреестр, Минобороны): машиночитаемый XML несёт юридически значимую подпись, рядом лежит PDF/DOCX-копия для печати, которая сама подписи не имеет. null, если такой связки нет. |
| signers | SignerInfoResult[] | Информация по каждому подписанту. Обычно один элемент. Заполняется и для OrphanSignature (подпись без документа): сертификат, цепочка доверия, классификация КЭП/НЭП, аккредитация УЦ, OCSP/CRL — всё, что не требует содержимого документа, отрабатывает; криптоматематика помечается signatureValid=false (документа для сверки нет). |
| errors | string[] | Ошибки, делающие подпись невалидной. |
| warnings | string[] | Предупреждения (deprecated алгоритмы, отсутствие OCSP-эндпойнта и т. п.). |
| signatureFileBase64 | string? | Заполняется только при returnSignatureFile=true. |
SignerInfoResult
Полная карточка подписанта. Поля сгруппированы для удобства.
Идентификация
| subjectCommonName | string | CN из Subject DN. |
| subject | string | Полный Subject DN. |
| issuer | string | Полный Issuer DN. |
| serialNumber | string | Серийный номер сертификата (hex). |
| subjectType | string? | «Физлицо» / «ИП» / «ЮЛ» / null — определяется по российским OID-ам. |
| signerShortName | string? | Компактное «Иванов И. И.» если есть фамилия и имя в attributes. |
| attributes | RussianSubjectAttributes | ИНН, ИНН ЮЛ, ОГРН, ОГРНИП, СНИЛС, email, surname, givenName, organization, organizationUnit, country, locality, title. |
Срок действия и алгоритмы
| certNotBefore | datetime | Начало срока действия сертификата (ISO-8601 UTC). |
| certNotAfter | datetime | Конец срока действия. |
| certificateTimeValid | bool | Был ли сертификат действителен в момент подписания (certNotBefore ≤ signingTime ≤ certNotAfter). Если этот флаг true, а certExpiredNow тоже true — типичная ситуация «подпись действительна, но сертификат к моменту проверки уже истёк»; isValid остаётся true по 63-ФЗ. |
| certExpiredNow | bool | true, если на момент проверки сертификат подписанта уже истёк (UtcNow > certNotAfter). Не влияет на isValid — нужен для UI/мониторинга, чтобы было видно расхождение «подписано когда-то валидным сертификатом, но сегодня он просрочен». Юридическая значимость такой подписи зависит от типа: для КЭП — определяется состоянием сертификата на момент подписания (63-ФЗ, ст. 11); для НЭП и иной — условиями соглашения сторон. |
| certNotYetValidNow | bool | true, если на момент проверки certNotBefore ещё не наступило (UtcNow < certNotBefore). Зеркальный кейс — обычно следствие расхождения часов или backdated-подписи. |
| digestAlgorithmOid | string | OID алгоритма хеширования. |
| digestAlgorithmName | string | Человекочитаемое имя. |
| signatureAlgorithmOid | string | OID алгоритма подписи. |
| signatureAlgorithmName | string | Имя. |
| signingTime | datetime? | Из подписанного атрибута signingTime (если есть). |
Криптопроверка и доверие
| signatureValid | bool | Прошла ли криптоматематика подписи. |
| signatureError | string? | Текст ошибки, если signatureValid=false. |
| trustStatus | string | Один из: Trusted, UntrustedRoot, BrokenChain, SignatureFailure, Expired, TrustStoreEmpty. |
| chainTrusted | bool | Завершилась ли цепочка на закреплённом anchor-е (ГУЦ Минцифры). |
| trustedRootSubject | string? | Subject корневого сертификата, если он в trust-store. |
| chain | CertificateChainLink[] | Цепочка leaf → ... → root. Каждый узел: subject, issuer, serialNumber, notBefore, notAfter, inTrustStore. |
| trustErrors | string[] | Подробности проблем доверия. |
Расширенная информация
| classification | SignatureClassification | kind (КЭП/НЭП/Иная), kindFull, reason, classes (КС1/КС2/КС3), subjectSignTool (СКЗИ), usesGost, issuedByAccreditedUc, isGoskey, deprecationWarnings. |
| cades | CadesProfile? | Уровень CAdES: BES, EPES, T, C, X-L, X Long Type 1, A. |
| timestamps | TimestampResult[] | Метки времени с проверенной TSA-подписью. |
| revocation | OcspResult? | OCSP-проверка (опционально, off by default). |
| revocationCrl | CrlResult? | CRL-проверка (опционально). |
| accreditation | AccreditationCheck? | Идентичность УЦ, выпустившего сертификат подписанта (issuingUcSki, issuingUcName) и окно его аккредитации (accreditedFrom, accreditedTo — null означает «действует»). Клиент сам вычисляет «аккредитован сейчас» или «аккредитован на момент подписания», сравнивая даты с signingTime. issuingUcSki=null → УЦ нет в реестре Минцифры. |
| counterSignatures | CounterSignatureInfo[] | Контр-подписи (id-aa-counterSignature). |
| signingCertBinding | object? | Проверка signingCertificateV2 (RFC 5126): Verified / Mismatch / Malformed / NotPresent. |
| certificateBase64 | string? | DER сертификата в base64 — только при returnCertificateFile=true. |
| checks | VerificationCheck[] | Список всех проверок, которые выполнились для этого подписанта, с унифицированным статусом. См. ниже. |
VerificationCheck
Унифицированная запись об одной из проверок конвейера верификации. Лежит в массиве signers[i].checks в том порядке, в котором проверки фактически срабатывают.
Поля
| id | string | Машиночитаемый идентификатор (см. каталог ниже). Стабилен — можно по нему фильтровать/группировать. |
| name | string | Короткое человеческое название. |
| description | string | Одна-две строки о том, что именно проверяется. |
| status | string | Один из: Ok, Failed, Warning, Skipped, Unreachable, NotApplicable. См. таблицу значений ниже. |
| details | string? | Подробности — текст ошибки, причина пропуска, время отзыва и т.п. Заполнено когда есть что сказать. |
| critical | bool | Если true и status="Failed" — этот провал привёл к IsValid=false в родительском документе. Если false — провал считается предупреждением и не отбивает подпись. |
Значения status
| Ok | Проверка отработала, всё в порядке. |
| Failed | Проверка отработала и провалилась. Если critical=true — родительский документ помечен невалидным. |
| Warning | Нефатальное замечание (устаревший алгоритм, аккредитация УЦ под вопросом). Подпись остаётся валидной. |
| Skipped | Проверка отключена в конфигурации (например EnableOcsp=false). |
| Unreachable | Проверка нуждается в сети, но эндпоинт не отозвался (OCSP/CRL responder, TLS-ГОСТ прокси). Результата нет, подпись из-за этого не отбивается. |
| NotApplicable | Проверка не имеет входных данных для этой подписи (нет counter-signatures, нет CRL endpoint в сертификате и т.п.). |
Каталог проверок (id → что делает)
| id | Что проверяет | critical | Влияние на IsValid |
|---|---|---|---|
| cms-parse | CMS / PKCS#7 SignedData разобран без ASN.1-ошибок. | да | Failed → IsValid=false |
| document-hash | Хеш документа совпадает с подписанным messageDigest. Ловит подмену документа. | да | Failed → IsValid=false (статус DocumentHashMismatch) |
| signature-math | Криптоматематика подписи против открытого ключа сертификата. | да | Failed → IsValid=false (InvalidSignature) |
| cert-time | Сертификат внутри окна NotBefore / NotAfter на момент проверки. | нет | Покрывается signatureValid и проверкой цепочки. |
| chain-anchor | Цепочка завершается закреплённым anchor-ом (ГУЦ Минцифры), каждое звено валидно. | да* | Failed → IsValid=false. UntrustedRoot → Warning + status=Untrusted (если включено RequireTrustedChain). |
| signing-cert-binding | id-aa-signingCertificateV2 (RFC 5035) — закрывает атаку подмены сертификата. | да | Failed → IsValid=false |
| revocation-ocsp | Статус отзыва через OCSP-сервис УЦ. Асинхронный: /verify по умолчанию возвращает status=Pending с endpoint-URL в details, клиент дёргает /api/v1/revocation и заменяет чек в финальном ответе. Inline только при ?withRevocation=true. | при Revoked | Revoked → IsValid=false. Unreachable / Skipped / Pending → не влияет. |
| revocation-crl | Статус отзыва через CRL. Поиск только в CRL-банке в памяти — никаких HTTP-запросов в момент проверки. Когда cRLDistributionPoint сертификата ещё не проиндексирован, проверка возвращается со status=Skipped и пометкой «CRL not yet indexed»; URL регистрируется в фоновой очереди, прокачивается на ближайшем прогоне CrlBankRefreshService, и следующая проверка отдаёт Good/Revoked мгновенно из памяти. | при Revoked | Revoked → IsValid=false. Skipped (не в банке) / Unreachable → не влияет. |
| accreditation | Был ли выпустивший УЦ аккредитован Минцифры на момент подписания (63-ФЗ). | нет | Не влияет на IsValid — только на классификацию (КЭП vs НЭП). |
| signature-kind | Классификация: КЭП / НЭП / Иная по политикам сертификата и алгоритму ключа. | нет | Не влияет на IsValid. |
| cades-level | Профиль CAdES (BES/EPES/T/C/X-L/A) и верификация TSA-меток. | нет | Не влияет на IsValid. |
| counter-signatures | Контрсигнатуры (id-aa-counterSignature) — каждая рекурсивно верифицируется. | нет | Не влияет на IsValid основной подписи. |
| algorithm-deprecation | Не используются ли устаревшие алгоритмы (SHA-1, MD5, ГОСТ 2001). | нет | Только предупреждение. |
Замечание про Unreachable: CleanSign fail-open — если OCSP/CRL responder недоступен или TLS-ГОСТ прокси упал, подпись не отбивается. В checks такой пункт будет Unreachable, а свойство isValid родительского документа останется true. Если revocation-check критичен для вашего use-case — фильтруйте на стороне клиента (checks.some(c => c.id.startsWith('revocation-') && c.status === 'Unreachable')).
Forward-compatibility: новые проверки могут появляться в каталоге, новые значения status — нет (текущие шесть фиксированы). Если ваш клиент не знает какой-то id — просто игнорируйте такую запись или рендерьте её как-нибудь нейтрально.
CertificateCheckResponse
Ответ POST /api/v1/cert/check. Структура простая:
| summary.total | int | Сколько файлов прислали. |
| summary.currentlyValid | int | Действительных сейчас. |
| summary.expiringSoon | int | Истекают в ближайшие 30 дней. |
| summary.expired | int | Уже истекли. |
| summary.trusted | int | Цепочка ведёт к закреплённому anchor-у. |
| summary.untrusted | int | Цепочка не выстроилась или anchor другой. |
| summary.revoked | int | Отозваны (по OCSP или CRL, если включены). |
| items[i] | CertificateCheckResult | fileName, source, subject, issuer, serialNumber, notBefore, notAfter, isCurrentlyValid, daysUntilExpiry, publicKeyAlgorithm, signatureAlgorithm, deprecationWarnings, classification, trust, accreditation, revocation, revocationCrl, attributes. Производный признак «истекает скоро» вычисляется на стороне клиента из daysUntilExpiry по своему порогу. |
Файлы ЭДО ФНС — расшифровка имён
В бандлах от операторов ЭДО (Контур, Диадок, Такском, СБИС) и из личного кабинета ФНС/ОФД встречаются XML-файлы с именами вида <префикс>_<тип>_<ИНН отправителя>_<ИНН получателя>_<дата>_<UUID>.xml. Префикс называет роль документа в обмене (приказы ФНС России о форматах ЭДО — например ММВ-7-6/138@, серия 383@).
Префиксы
| Префикс | Расшифровка | Роль в обмене |
|---|---|---|
| ON_ | Основной документ налогоплательщика | Содержательный документ — то, что отправитель шлёт получателю (УПД, счёт-фактура, отчёт по требованию). |
| IZ_ | Извещение о получении документа | «Я подтверждаю, что документ дошёл по транспорту». Подписывается КЭП оператора или получателя. |
| KV_ | Квитанция о приёме документа | «Документ проверен по формату и принят к рассмотрению». Подписывается КЭП ФНС. |
| TR_ | Транспортная информация (TR_INFSOOB) | Сопроводительный конверт с метаданными: отправитель / получатель / дата / идентификаторы транзакции. |
| DP_ | Документ продавца / отправителя | Документ от налогоплательщика в адрес ФНС или от продавца покупателю. |
Примеры из реальных бандлов
| Файл | Что это |
|---|---|
| ON_DOCNPNO_… | Документ налогоплательщика, направляемый в налоговый орган (ответ на требование ФНС). |
| IZ_ONDOCNPNO_… | Извещение о получении ON-документа — получатель/оператор подтвердил приём по транспорту. |
| KV_ONDOCNPNO_… | Квитанция ФНС о приёме ON-документа после форматной проверки. |
| TR_INFSOOB.xml | Транспортная инфосообщение — обвязка пакета. |
| DP_PDOTPR_… | Документ продавца, передающий товары/услуги по требованию (универсальный передаточный документ — УПД). |
| ON_NSCHFDOPPR_… | НСЧФ — счёт-фактура с признаками операций передачи. Это сам УПД-документ. |
Как идёт обмен
- Налогоплательщик подписывает
ON+TRсвоей КЭП → шлёт оператору ЭДО (Контур, Такском, Диадок и т.д.). - Оператор подписывает
IZсвоей КЭП → шлёт в ФНС. - ФНС проверяет формат, подписывает
KVсвоей КЭП → шлёт обратно через оператора. - Оператор подписывает свою
IZнаKV→ отдаёт налогоплательщику.
Итого один обмен документом — пакет из 3–5 подписанных XML-файлов, между ними цепочка извещений и квитанций. Все подписи — отдельные .sig (CMS detached) либо встроенные в <Signature> внутри XML.
confirmation.xml
Файл confirmation.xml — это уже не ФНС-формат, а внутренний формат конкретного оператора ЭДО (Goskey / Диадок / СБИС): подтверждение принятия документа в системе оператора, ID транзакции и т.п. Имя стандартизировано на уровне оператора, не ФНС.
Что делает CleanSign
Пакет из таких файлов обрабатывается естественно: каждая XML + её .sig верифицируются отдельно. Если имена файлов рассогласованы (некоторые операторы кладут confirmation.sig рядом с XML, имя которого не совпадает с реальным подписанным документом) — срабатывает сопоставление по содержимому через messageDigest в CMS, и пара восстанавливается корректно.
Типичные интеграции
Сценарии, в которых API применяется на практике.
Учётные системы (1С, SAP, ERP)
При приёме входящего УПД, акта или счёта-фактуры файл автоматически направляется на /api/v1/verify; проводка блокируется, если подпись контрагента невалидна или сертификат отозван.
Операторы ЭДО
Кросс-проверка пакетов от смежных операторов и ФНС: PDF + .sig, ON_DOCNPNO, KV-квитанции, confirmation.*. Автоматическое сопоставление по содержимому, единый формат отчёта.
Финтех, банки, факторинг
Перед выкупом дебиторской задолженности выполняется автоматическая проверка договора поставки: валидная КЭП обеих сторон, цепочка до ГУЦ Минцифры, аккредитация УЦ на момент подписания.
Госорганы и B2G
Приём электронных обращений: проверка подписи заявителя, классификация (КЭП, НЭП), привязка к ФЛ, ИП или ЮЛ по ИНН, СНИЛС и ОГРН, выявление машиночитаемой доверенности (МЧД).
Мониторинг сертификатов через cron
Эндпоинт /api/v1/cert/check запускается раз в сутки по сертификатам ЭДО и API-партнёров; формирует оповещение за Х дней до истечения, при отзыве сертификата или при потере аккредитации УЦ.
curl -F files=@cert.cer \
https://api.cleanvoice.ru/cleansign/api/cert/check \
| jq '.items[0].daysUntilExpiry < 30'
Долгосрочное хранение
При помещении документа в архив фиксируется уровень CAdES (от BES до A), валидируются метки времени, сохраняется цепочка сертификатов и снимок реестра аккредитации УЦ в качестве доказательственной базы.
Состав подписки
Подписка включает не только доступ к API, но и операционное обслуживание сервиса в режиме 24/7:
| Компонент | Состав |
|---|---|
| Актуальный trust-store | Автоматическое обновление: загрузка новых промежуточных сертификатов через AIA, обработка ротации ключей УЦ, актуальные точки распространения CRL. |
| Синхронизация с реестром Минцифры | Ежедневные обновления с добавление новых аккредитованных УЦ, аннулирования, изменения статуса. |
| Сопровождение форматов | Адаптация движка к новым форматам (Goskey 2.x, новые OID Минцифры, изменения 63-ФЗ). Обновления применяются на стороне сервиса без действий со стороны клиента. |
| Производительность | Горизонтальное масштабирование под пиковую нагрузку. |
| SLA и поддержка | Целевая доступность 99.95%. |
Запросить стоимость
В письме укажите сценарии использования и ожидаемый объём верификаций в месяц.