Блог · Для розробників

Перевірка електронного підпису на сайті: криптографія, ланцюжок, OCSP і мітки часу

Опубліковано

«Підпис дійсний» — це не одна перевірка, а чотири. Розбираємо, з чого складається справжня валідація КЕП, чим відрізняються attached і detached підписи, які поля повертає перевірка і як вбудувати її на свій сайт кількома рядками коду.

Опубліковано 7 серпня 2026


Коротка відповідь. Повна перевірка електронного підпису (ЕЦП/КЕП) — це чотири рівні: математика підпису (чи відповідає підпис документу й ключу), ланцюжок довіри (чи простежується сертифікат до кореневого ЦСК), статус сертифіката (чи не відкликано його — OCSP/CRL) і мітки часу (коли підпис справді існував — TSP). Віджет verify від DSTUcrypt виконує всі чотири рівні прямо у браузері, сам визначає формат файлу (.p7s, PDF, XML, ASiC) і повертає структурований результат по кожному підписанту — включно з полем accredited, яке відповідає на головне питання: це КЕП чи ні. Для разових перевірок є безкоштовний інструмент dstucrypt.com.ua/verify — без реєстрації.

Що насправді означає «підпис дійсний»: чотири рівні перевірки

Коли сервіс каже «підпис дійсний», за цими словами може ховатися дуже різний обсяг роботи. Юридично значуща валідація КЕП складається з чотирьох незалежних перевірок — і провал будь-якої з них означає, що документу довіряти не можна:

Рівень На яке питання відповідає Як перевіряється Поля результату
1. Математика підпису Чи створений підпис саме для цього документа саме цим ключем; чи не змінювали документ після підпису Перевірка підпису ДСТУ 4145 і геша документа (ГОСТ 34.311 або «Купина» ДСТУ 7564 ) valid , status
2. Ланцюжок довіри Чи виданий сертифікат підписанта справжнім акредитованим надавачем, а не згенерований будь-ким Побудова ланцюжка сертифікатів до офіційного кореня ЦЗО accredited
3. Статус сертифіката Чи не відкликано сертифікат (компрометація ключа, звільнення співробітника) Онлайн-запит OCSP або перевірка за списком відкликання CRL ocspStatus , crlStatus
4. Мітки часу Коли підпис справді існував — і чи був сертифікат чинним саме тоді Перевірка кваліфікованої мітки часу TSP у контейнері signingTime , timestampTime

Зверніть увагу на четвертий рівень: без мітки часу поле signingTime — це лише заявлений час, який підписант міг виставити довільно. Довіреним є timestampTime — час, засвідчений кваліфікованим TSP-сервером.

Чому «зелена галочка» без ланцюжка і статусу — це не перевірка

Найпоширеніша помилка саморобних перевірок — зупинитися на першому рівні. Бібліотека перевірила математику, підпис зійшовся — показуємо галочку. Але сама по собі коректна математика доводить лише те, що хтось підписав документ якимось ключем. Пару «ключ + сертифікат» може згенерувати будь-хто за секунди і вписати в сертифікат довільне ПІБ.

Реальну довіру дає лише ланцюжок: сертифікат підписанта → проміжні сертифікати → корінь центрального засвідчувального органу (ЦЗО). І навіть справжній сертифікат від акредитованого надавача міг бути відкликаний учора — тому потрібен третій рівень, актуальний статус за OCSP чи CRL. Перевірка, яка пропускає рівні 2–4, створює небезпечну ілюзію: користувач бачить «дійсний», а юридично документ може не важити нічого.

Як це зроблено в DSTUcrypt. Віджет verify завжди виконує повну валідацію: криптографія + ланцюжок до кореня ЦЗО + статуси OCSP/CRL + мітки часу TSP. Формат підпису визначається автоматично за вмістом файлу, а поле accredited в результаті прямо відповідає, чи це КЕП. Для разових перевірок є безкоштовний онлайн-інструмент /verify — та сама повна валідація, без реєстрації.

Вкладений (attached) і відокремлений (detached) підпис

Файл .p7s буває двох видів, і від цього залежить, як викликати перевірку:

  • Вкладений (attached) — документ запакований усередину CMS-контейнера разом із підписом. Це один самодостатній файл: для перевірки другим аргументом передається null, а оригінальний документ повертається у полі content результату.
  • Відокремлений (detached) — контейнер містить лише підпис, а документ лежить окремим файлом (типова пара «contract.pdf + contract.pdf.p7s»). Без оригіналу перевірити нічого: другим аргументом обовʼязково передаються dataBytes — байти вихідного документа.

Практичне правило: якщо поруч із .p7s лежить файл із такою самою назвою без розширення підпису — це майже напевно detached, і перевіряти їх треба разом.

Автовизначення формату: CMS, PDF, XML, ASiC

Український документообіг живе не лише в .p7s. Підпис може сидіти всередині PDF (PAdES), в XML-документі (XAdES) або в ZIP-контейнері ASiC. Віджет не вимагає вказувати формат — він розпізнає його за вмістом файлу:

Вміст файлу Родина підпису Типове розширення
CMS/PKCS#7-структура CAdES .p7s
PDF-документ PAdES .pdf
XML-документ XAdES .xml
ZIP-контейнер ASiC-S / ASiC-E .asics , .asice

Це знімає з інтегратора цілий клас помилок: користувач просто передає файл, а визначений формат повертається у полі format кожного підписанта (наприклад, 'CAdES-T'). Про те, чим родини відрізняються і яку обрати для підпису, — окрема стаття про формати CAdES, PAdES, XAdES і ASiC.

Що повертає перевірка: розбір полів signers

Результат — це загальний вердикт valid плюс масив signers: по одному елементу на кожного підписанта (у документі їх може бути кілька). Кожен елемент містить:

  • valid і status — вердикт по цьому підписанту: TOTAL-VALID (усе добре), TOTAL-FAILED (перевірка провалена) або INDETERMINATE (даних недостатньо для остаточного висновку).
  • accredited — головне поле для юридичної кваліфікації. true — сертифікат виданий акредитованим надавачем і простежений до кореня ЦЗО, тобто це КЕП. false — підпис криптографічно дійсний, але не КЕП. null — дані довіри недоступні, акредитацію не перевірено. Чому ця різниця важлива юридично — у статті про відмінність КЕП, ЕЦП і УЕП.
  • format — автоматично визначений формат і рівень підпису.
  • signingTime / timestampTime — заявлений час підпису і довірена мітка часу TSP.
  • ocspStatus / crlStatus — статус сертифіката за OCSP або CRL, якщо перевірявся.
  • signerCertId, signerName, signerOrg, signerCode — ідентифікатор сертифіката, ПІБ або назва підписанта, організація та РНОКПП/ЄДРПОУ з сертифіката.

Код: перевірка підпису на вашому сайті

Уся інтеграція — один імпорт SDK; віджет працює в iframe на нашому origin, нічого хостити в себе не треба:

повна перевірка підпису — віджет verify

import { embed } from 'https://dstucrypt.io/embed/dstucrypt-embed.mjs';

const verifier = await embed('verify', { mount: 'modal' });

// другий аргумент — ЛИШЕ для відокремленого (detached) підпису;
// для вкладеного (attached) передавайте null
const report = await verifier.verify(signatureBytes, null);

console.log(report.valid);          // сумарний вердикт: усі підписи дійсні
for (const s of report.signers) {
  s.status;         // 'TOTAL-VALID' | 'TOTAL-FAILED' | 'INDETERMINATE'
  s.valid;          // вердикт по цьому підписанту
  s.accredited;     // true — акредитований надавач (це КЕП); false — ні; null — не перевірено
  s.format;         // напр. 'CAdES-T' — формат визначено автоматично
  s.signingTime;    // заявлений час підпису
  s.timestampTime;  // довірена мітка часу TSP, якщо є
  s.ocspStatus;     // статус сертифіката за OCSP (напр. 'GOOD')
  s.crlStatus;      // …або за CRL
  s.signerName;     // ПІБ/назва підписанта з сертифіката
  s.signerOrg;      // організація
  s.signerCode;     // РНОКПП/ЄДРПОУ
  s.signerCertId;   // ідентифікатор сертифіката
}
report.content?.download('document.pdf'); // вкладені дані attached-підпису

Важливе застереження для критичних сценаріїв: браузерна перевірка чудова для UX, але браузер контролює користувач. Якщо на підставі вердикту рішення ухвалює ваш бекенд (прийняти документ, зарахувати платіж) — передайте підпис на сервер і перевірте авторитетно через POST /api/verify: він виконує ту саму повну валідацію нативним ядром і так само повертає accredited по кожному підписанту.

Разова перевірка без коду: безкоштовний інструмент

Якщо вам не потрібна інтеграція, а треба просто перевірити конкретний файл — відкрийте dstucrypt.com.ua/verify. Це безкоштовний онлайн-інструмент без реєстрації: перетягніть .p7s, підписаний PDF, XML чи ASiC-контейнер — і отримаєте повний звіт по кожному підписанту: вердикт, КЕП чи ні, надавач, статус сертифіката і мітки часу. Для detached-підпису інструмент попросить докласти оригінальний файл.

Поширені запитання

Як перевірити підпис .p7s онлайн безкоштовно?

Відкрийте безкоштовний інструмент dstucrypt.com.ua/verify і перетягніть файл підпису — реєстрація не потрібна. Формат (.p7s, PDF, XML, ASiC) визначається автоматично, а перевірка повна: криптографія, ланцюжок довіри, статус сертифіката за OCSP/CRL і мітки часу.

Що означає поле accredited у результаті перевірки?

Це відповідь на питання, чи є підпис КЕП: true — сертифікат підписанта виданий акредитованим надавачем і простежений до кореня ЦЗО, тобто це кваліфікований електронний підпис; false — підпис криптографічно дійсний, але не КЕП; null — дані довіри недоступні, акредитацію не перевірено.

Коли потрібно передавати оригінальний файл разом із підписом?

Лише для відокремленого (detached) підпису, коли .p7s містить тільки підпис без даних. У виклику verify(signatureBytes, dataBytes) другим аргументом передайте оригінал. Для вкладеного (attached) підпису дані вже всередині контейнера — передавайте null, а вкладений вміст повернеться в полі content.

Чи можна довіряти перевірці підпису в браузері?

Для UX — так: віджет чесно виконує повну перевірку у браузері й показує користувачу вердикт. Але якщо на підставі перевірки рішення ухвалює ваш бекенд (прийняти документ, зарахувати платіж), перевіряйте підпис на сервері через POST /api/verify — вердикту, що прийшов із браузера клієнта, довіряти не можна.

Читайте також

Повна перевірка КЕП на вашому сайті — за 10 хвилин

Готові віджети перевірки, підпису та шифрування за ДСТУ. Криптографія, ланцюжок, OCSP/CRL і мітки часу — з коробки. Спробуйте безкоштовну перевірку або підключіть віджет: на кожному новому домені — 7 днів безкоштовно.

Живе демоЯк підключити

Спробуйте КЕП на своєму сайті

Готові віджети підпису, перевірки та входу за ДСТУ. На кожному новому домені — 7 днів безкоштовно.