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

Як додати КЕП на сайт за 10 хвилин: iframe-віджет без бекенду і без криптографії

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

Покроковий туторіал: один імпорт SDK, виклик `embed('sign')` — і на вашій сторінці працює електронний підпис за ДСТУ. Ключ користувача не покидає iframe, а ви отримуєте готовий підпис для свого бекенда.

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


Коротка відповідь. Щоб додати КЕП на сайт, не потрібні ні власний криптографічний бекенд, ні знання PKI. Робите один імпорт SDK з https://dstucrypt.io/embed/dstucrypt-embed.mjs, викликаєте embed('sign', { mount: 'modal' }) — і на вашій сторінці з'являється модалка підпису. Користувач обирає файл ключа і вводить пароль всередині ізольованого iframe, а ваш код отримує готовий CMS-підпис: signature.base64 для передачі на бекенд або signature.download() для збереження файлом. Нижче — повний шлях від нуля до першого підписаного документа.

Що отримаєте в результаті — і чого робити не доведеться

Після десяти хвилин інтеграції на вашому сайті працює справжній підпис документів: користувач натискає кнопку, бачить модалку, обирає свій файловий ключ, вводить пароль — і ваш JavaScript отримує проміс із результатом. У результаті — сам підпис (байти або base64), ідентифікатор сертифіката підписанта signerCertId і поле accredited, за яким ви відрізняєте кваліфікований підпис (КЕП) від просто дійсного.

Не менш важливо, чого робити не треба. Не треба хостити в себе файли віджета, ядро чи .wasm — усе вантажиться з origin dstucrypt.com.ua, а SDK сам будує адреси. Не треба писати жодного рядка криптографії: підпис за ДСТУ 4145 рахує перевірене криптоядро, скомпільоване у WebAssembly. І не треба розбиратися в нутрощах PKI — мітки часу (TSP), OCSP і CRL ходять через вбудований проксі з автоматичним фолбеком, вам нічого не налаштовувати.

Чому саме iframe-віджет. Ви нічого не хостите в себе — жоден файл сервісу не лежить на вашому сервері. На вашому боці немає жодної криптографії — отже, і нічого сертифікувати чи оновлювати. Версія віджета завжди актуальна: виправлення й нові формати з'являються без перезбирання вашого сайту. А головне — ключ і пароль користувача ізольовані всередині iframe на іншому origin: навіть XSS на вашій сторінці до них не дотягнеться.

Крок 1. Один імпорт замість бекенду

Уся інтеграція починається (і майже закінчується) одним рядком — імпортом ES-модуля просто на вашій сторінці:

крок 1 — імпорт SDK на сторінці

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

Ні npm-пакета, ні збірки, ні ключів API в коді. SDK будує адресу віджета зі свого origin, тому ви не пишете URL файлів вручну і не тримаєте копій у себе (self-host навмисно заборонений — ізоляція ключа працює лише з origin сервісу). Для локальної розробки є режим localhost — він завжди безкоштовний.

Крок 2. Створюємо віджет: embed('sign', { mount: 'modal' })

Виклик embed() створює окремий iframe під один віджет і повертає його екземпляр. Разом із кроком 3 мінімальний робочий приклад виглядає так:

кроки 2–3 — повний мінімальний приклад

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

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

// fileBytes: File | Blob | ArrayBuffer | Uint8Array | string
const { signature, signerCertId, accredited } = await signer.sign(fileBytes, {
  format: 'CAdES-BES',
});

signature.download('document.p7s');  // віддати підпис файлом

На sign() віджет відкриває модалку: користувач обирає файл ключа, вводить пароль — і проміс резолвиться результатом. Дані ви передаєте як є: File з інпута, ArrayBuffer, Uint8Array чи рядок — конвертації в base64 на вході не потрібні.

Крок 3. Обробляємо результат підпису

Методи повертають байти в обгортці Bytes — з неї зручно взяти будь-яке подання. Найтиповіший сценарій — надіслати підпис на свій бекенд:

обробка результату + помилки

try {
  const { signature, accredited } = await signer.sign(fileBytes);

  await fetch('/api/documents/42/signature', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ signature: signature.base64, accredited }),
  });
  // або: signature.bytes (Uint8Array), signature.blob(), signature.size
} catch (e) {
  if (e.code === 'not_licensed' || e.code === 'load_failed') return; // модалку вже показано
  showError('Не вдалося підписати: ' + e.message); // скасовано, невірний пароль тощо
}

Поле accredited варто зберігати поруч із підписом: true означає, що сертифікат виданий акредитованим надавачем — тобто це саме КЕП. А коли рішення про допуск ухвалює бекенд, продублюйте перевірку авторитетним серверним POST /api/verify.

Який формат підпису обрати для старту

Опція format приймає повний рядок формату — CAdES, PAdES (PDF), XAdES (XML), ASiC. Для старту вибір простий:

Формат Що це Коли брати
CAdES-BES базовий CMS-підпис, файл .p7s ; за замовчуванням внутрішній документообіг, перший запуск, офлайн-сценарії
CAdES-T те саме + кваліфікована мітка часу (TSP) коли важливо довести момент підписання; потребує онлайн-TSP, який SDK бере сам

Почніть із CAdES-BES і перемкніться на CAdES-T, щойно знадобиться мітка часу, — це зміна одного рядка. Про решту рівнів (CAdES-C, CAdES-XL, PAdES для PDF, XAdES для XML, контейнери ASiC) ми готуємо окрему статтю про формати підпису.

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

Які ключі підтримуються

Віджет відкриває всі поширені файлові контейнери українських надавачів: PKCS#12 (.p12/.pfx), JKS, PKCS#8 і Key-6.dat. Користувачу не треба знати, що в нього за файл: віджет сам відкриє контейнер і обере підписний ключ за keyUsage. Якщо контейнер без сертифіката — віджет запропонує його підвантажити. Апаратні токени не підтримуються — лише файлові ключі.

Mount-режими: модалка чи inline-блок

Опція mount визначає, де живе віджет. 'modal' (за замовчуванням) — модальне вікно поверх сторінки, що відкривається на час операції; iframe у ньому автоматично росте під вміст. Альтернатива — вбудувати віджет у власний блок сторінки, передавши CSS-селектор або Element:

inline-режим — віджет усередині вашого блоку

<!-- на сторінці: -->
<div id="sign-box"></div>

const signer = await embed('sign', { mount: '#sign-box' });
const { signature } = await signer.sign(fileBytes, { format: 'CAdES-T' });

Inline-режим зручний, коли підпис — центральна дія сторінки (кабінет документообігу, сторінка договору), а модалка — коли підпис лише крок у сценарії. Коли віджет більше не потрібен, викличте widget.destroy().

Скільки це коштує

Ліцензія прив'язується до домену. Кожен новий домен автоматично отримує 7 днів безкоштовно — без реєстрації, просто підключіть віджет. Далі базова підписка — 4 500 грн/міс або 38 880 грн/рік за домен; оплата онлайн через LiqPay на сторінці /buy, керування доменами — в кабінеті. localhost для розробки безкоштовний завжди.

Що далі: перевірка, вхід за КЕП, шифрування

Підпис — лише один із шести віджетів. Тим самим embed() підключаються verify (перевірка підпису з деталями по кожному підписанту), auth (вхід на сайт за КЕП із серверним підтвердженням ідентичності), encrypt/decrypt (шифрування CMS EnvelopedData) і cert (розбір та онлайн-статус сертифікатів). Починаються вони так само — з одного імпорту, який ви вже зробили.

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

Чи треба щось встановлювати або хостити у себе, щоб додати КЕП на сайт?

Ні. Ви робите один імпорт SDK з https://dstucrypt.io/embed/dstucrypt-embed.mjs — усі файли віджета і криптографічне ядро завантажуються з нашого origin. SDK сам будує адресу віджета, тож ви не пишете URL файлів і нічого не хостите у себе.

Чи потрапляє ключ або пароль користувача на мій сервер?

Ні. Уся криптографія виконується у браузері користувача (WebAssembly) всередині iframe на origin dstucrypt.io. Приватний ключ і пароль не потрапляють ні в код вашої сторінки, ні на ваш сервер, ні на сервери DSTUcrypt.

Скільки коштує віджет КЕП для сайту?

Кожен новий домен отримує 7 днів безкоштовно автоматично — просто підключіть віджет. Далі базова підписка 4 500 грн/міс або 38 880 грн/рік за домен, оплата онлайн через LiqPay.

Який формат підпису обрати на старті?

Для старту достатньо CAdES-BES — базового формату за замовчуванням (файл .p7s). Якщо потрібна кваліфікована мітка часу, вкажіть format:'CAdES-T' — мітку SDK отримає сам через вбудований проксі, налаштовувати нічого не треба.

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

Спробуйте: КЕП на вашому сайті вже сьогодні

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

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

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

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