Документація · Віджети

Підпис документів

Віджет sign накладає КЕП на будь-які дані. Користувач обирає файл ключа і вводить пароль всередині iframe — на вашу сторінку вони не потрапляють; назад приходить лише готовий підпис.

Мінімальний приклад

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

const signer = await embed('sign', { mount: 'modal' });

const { signature } = await signer.sign(fileBytes, { format: 'CAdES-T', digest: 'gost-34311' });

signature.download('document.p7s');       //  віддати файл користувачу
//  або на бекенд:
await fetch('/api/save', { method: 'POST', body: signature.bytes });

signer.destroy();

API

const { signature, signerCertId, accredited } = await signer.sign(data, options);
  • data — File | Uint8Array | ArrayBuffer | рядок.
  • signature — Bytes з готовим підписом.
  • signerCertId — ідентифікатор сертифіката підписанта.
  • accredited — чи це КЕП: true — сертифікат від акредитованого АЦСК; false — ні (підпис без статусу КЕП); null — акредитацію не перевіряли. Це поле також повертається користувачу з попередженням у самому віджеті.

Параметри options

Параметр За замовч. Опис
format 'CAdES-BES' формат і рівень підпису (див. таблицю нижче)
detached false відокремлений підпис (дані не вкладаються в контейнер)
fileName 'document' ім'я файла всередині ASiC-контейнера
digest 'gost-34311' геш підпису: 'gost-34311' (ДСТУ ГОСТ 34.311-95, за замовчуванням — його приймають держвалідатори) або 'kupyna-256' (ДСТУ 7564:2014, «Купина»). Разом із гешем автоматично береться узгоджений алгоритм підпису ДСТУ 4145. Для RSA/ECDSA-ключів геш обирає ядро
includeContentTS false мітка часу на самі дані (contentTS) — для CAdES-T і вище
checkStatus авто для -C/-XL вкласти OCSP-статус сертифіката в контейнер. Для CAdES-C і CAdES-XL вмикається автоматично (без даних відкликання ці рівні неповні); для інших рівнів можна ввімкнути вручну. Потребує онлайн-OCSP надавача

Формати підпису

Підтримується 16 форматів — чотири родини, у кожній свої рівні. Що вищий рівень, то більше даних для довгострокової й офлайн-перевірки вкладається у підпис.

CAdES — підпис CMS, файл .p7s (будь-які дані):

format Рівень Що додає
CAdES-BES базовий підпис без мережі
CAdES-T + мітка часу TSP на підпис
CAdES-C + референси посилання на сертифікати й OCSP/CRL для перевірки
CAdES-XL + повні дані самі сертифікати й OCSP/CRL (довгострокова перевірка)

PAdES — підпис вбудовано в PDF, файл .pdf:

format Рівень
PAdES-B-B базовий
PAdES-B-T + мітка часу
PAdES-B-LT + дані для довгострокової перевірки
PAdES-B-LTA + архівна мітка часу

XAdES — підпис у XML, файл .xml:

format Рівень
XAdES-BES базовий
XAdES-B-T + мітка часу
XAdES-B-LT + дані для довгострокової перевірки
XAdES-B-LTA + архівна мітка часу

ASiC — ZIP-контейнер (оригінал + підпис):

format Файл Рівень
ASiC-S-BES .asics простий контейнер, базовий
ASiC-S-T .asics простий контейнер, + мітка часу
ASiC-E-BES .asice розширений контейнер, базовий
ASiC-E-T .asice розширений контейнер, + мітка часу

Про назви рівнів. CAdES вживає стару номенклатуру (-BES/-T/-C/-XL), а XAdES і PAdES — новішу baseline-схему ETSI (-BES/-B-T/-B-LT/-B-LTA). Тому рівень «з міткою часу» — це CAdES-T, але XAdES-B-T і PAdES-B-T.

Геш за замовчуванням — ДСТУ ГОСТ 34.311-95 (digest:'gost-34311'): саме пару «підпис ДСТУ 4145 + геш ГОСТ 34.311» сьогодні приймають держвалідатори (Дія, ЦЗО). Сучасну «Купину» (ДСТУ 7564:2014) вмикайте явно — digest:'kupyna-256' — для ключів, що її підтримують. Коли держсистеми перейдуть на «Купину», її можна зробити дефолтом одним рядком, без перезбирання.

Мітки часу — нічого не налаштовуєте

Для CAdES-T і вище мітку часу ставлять наші вбудовані TSP-сервери з автоматичними фолбеками (якщо один недоступний — запит повторюється до наступного). CORS-проксі теж наш. Жодних tspUrl/proxyUrl у вашому коді.

У базовій підписці — 1 000 міток часу на добу на домен. Понад ліміт віджет поверне помилку TSP_QUOTA («Денний ліміт міток часу вичерпано»).

Ключ у застосунку: Дія.Підпис і Smart ID

Крім файлового ключа, віджет уміє підписувати ключем, який лежить у застосунку користувача — Дія або Приват24. Склад способів задаєте ви:

const signer = await embed('sign', { providers: ['file', 'diia', 'smartid'] });
const { signature, provider } = await signer.sign(file, { fileName: file.name });
//  provider — чим користувач урешті підписав: 'file' | 'diia' | 'smartid'

Якщо способів кілька, користувач обирає у вікні підпису; якщо один — перемикача немає взагалі. Документ при цьому нікуди не йде: до надавача передається лише геш. Подробиці, обмеження й відмінності двох надавачів — на сторінці Дія.Підпис і Smart ID.

Коротко про те, що змінюється в коді:

  • digest задавати не треба — кожен надавач приймає свій алгоритм, і віджет підставляє потрібний сам (Дія — ГОСТ 34.311, Smart ID — Купина-256).
  • signBatch() економить дії користувача: кілька файлів підписуються однією сесією — один QR і одне підтвердження в застосунку.
  • format працює як завжди, включно з довгостроковими рівнями.
  • detached теж: надавач фізично повертає відокремлений підпис, а віджет за замовчуванням вкладає у нього ваші дані — значення підпису не змінюється.

Що бачить користувач

Одна кнопка «Підписати»: обрати файл ключа (PKCS#12/PFX, JKS, PKCS#8, Key-6.dat), ввести пароль — віджет сам відкриє контейнер, обере підписний ключ (за keyUsage) і підпише. Якщо контейнер без сертифіката — з'явиться поле для окремого файла сертифіката.

Помилки показуються людською мовою: «Невірний пароль до ключа», «Сервер позначок часу недоступний» тощо.

Підписувати без пароля щоразу

Щоб користувач не обирав ключ і не вводив пароль при кожному підписі, увімкніть автоматичний режим: ключ зберігається у віджеті (окремо для вашого домену, зашифрований PIN-кодом), і sign() виконується без модалки.

Мультипідпис — кілька підписантів

Опція «Кілька підписантів» дозволяє додати ще одного підписанта до вже підписаного документа (CMS) — метод coSign(). Це платна опція, що вмикається окремо для домену (у тарифах; у тріалі доступна для перевірки).

const signer = await embed('sign', { mount: 'modal' });

//  existingSignature — вже готовий .p7s (від першого підписанта),
//  data — ті самі дані, що підписувались.
const { signature } = await signer.coSign(existingSignature, data);

signature.download('document.p7s');   //  CMS уже з двома підписами
  • Відкриється звична модалка вибору ключа — підписує другий користувач.
  • Повертає той самий CMS із доданим SignerInfo (паралельний підпис).
  • Якщо опцію не оплачено для домену — метод кине помилку з error.code === 'MULTISIGN_NOT_ENABLED'.

Типові помилки в коді інтегратора

error.code / повідомлення Причина
LICENSE_INACTIVE домен не активовано (завершився тріал/підписка)
MULTISIGN_NOT_ENABLED опція «Кілька підписантів» не підключена для домену
TSP_QUOTA вичерпано денний ліміт міток часу
CANCELLED користувач натиснув «Скасувати»