Документація · Можливості

Автоматичний режим (збережений ключ)

Щоб користувач не обирав файл ключа й не вводив пароль щоразу, ключ можна зберегти у віджеті. Далі операція виконується без вибору файла й пароля до контейнера — а з ttlMinutes і взагалі без жодної взаємодії.

Типовий сценарій: підписати 50 накладних поспіль, працювати цілий день у кабінеті бухгалтера, масовий підпис у ERP.

Режим доступний для трьох віджетів, що працюють із ключем:

Віджет Поведінка зі збереженим ключем
sign — підпис тихо, без модалки (за ttlMinutes)
decrypt — розшифрування тихо, без модалки (за ttlMinutes)
auth — вхід за КЕП напівавтоматично: файл і пароль не потрібні, але користувач завжди тисне «Увійти»

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

Спочатку — увімкніть функцію

Автоматичний режим вимкнено за замовчуванням: віджет поводиться як звичайно (ключ і пароль щоразу), і жодного UI збереження користувач не бачить. Умикає його інтегратор — явним параметром:

const signer = await embed('sign', { session: true });   //  ← увімкнути збереження ключа

//  так само для інших віджетів, що працюють із ключем:
const dec  = await embed('decrypt', { session: true });
const auth = await embed('auth',    { session: true });
Значення session Поведінка
не задано функція вимкнена: ключ і пароль щоразу (за замовчуванням)
true ключ зберігається; PIN питається щоразу, файл і пароль до контейнера — ні
{ ttlMinutes: 60 } PIN не питати 60 хв у межах вкладки — підпис іде без взаємодії
{ noPin: true } показати користувачу галочку «Не використовувати PIN» (за замовчуванням її немає)

Крок 1. Завантажити ключ наперед

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

const signer = await embed('sign');

//  «Завантажити ключ» — окремою кнопкою у вашому інтерфейсі
const st = await signer.session.setup();
// st = { saved: true, unlocked: true, needsPin: true, label: 'key.p12', … }

Ключ зберігається в нашому origin (dstucrypt.com.ua) у зашифрованому вигляді, окремим записом для вашого домену.

Крок 2. Далі — без файла й пароля

//  той самий виклик; що побачить користувач — залежить від налаштування:
const { signature } = await signer.sign(doc, { format: 'CAdES-T', digest: 'gost-34311' });
  • session: true (за замовчуванням) — відкриється компактне вікно з одним полем PIN. Ні файла, ні пароля до контейнера.
  • session: { ttlMinutes: N } — перші N хвилин після введення PIN модалка взагалі не відкривається: підпис виконується тихо. Режим для масових операцій (підписати 50 накладних поспіль).

ttlMinutes — це компроміс: що довший інтервал, то зручніше користувачу і то більше вікно, у якому скомпрометована сторінка могла б підписати щось без його відома.

Ключ можна зберегти й «попутно»: у звичайному вікні підпису є галочка «Запам'ятати ключ на цьому сайті» з полем PIN. session.setup() — це той самий механізм, але окремим кроком, коли зручніше налаштувати все наперед (наприклад, кнопка «Підключити ключ» у налаштуваннях кабінету).

Керування сесією з вашої сторінки

await signer.session.setup();                     //  завантажити/замінити ключ

const st = await signer.session.status();
// { saved: true, unlocked: false, needsPin: true, label: 'key.p12', unlockedUntil: … }

if (st.saved && !st.unlocked) {
    await signer.session.unlock({ pin: userPin });   //  свій PIN-екран у вашому UI
}

await signer.session.lock();     //  заблокувати (ключ лишається збереженим)
await signer.session.forget();   //  прибрати ключ з браузера зовсім
Поле status() Що означає
saved для цього домену збережено ключ
unlocked сесія активна — підпис піде без взаємодії
needsPin ключ захищено PIN-кодом (режим за замовчуванням)
label ім'я файла ключа (для показу користувачу)
unlockedUntil час, до якого сесія лишається розблокованою

Якщо unlocked: false, а ви просто викличете sign() — віджет відкриє модалку й попросить PIN. Тобто робочий код не ламається в жодному стані.

Де і як зберігається ключ

  • Сховище — localStorage нашого origin. Ваш сайт не має до нього доступу (Same-Origin Policy), інші сайти — теж.
  • Запис прив'язаний до вашого домену. Наш localStorage спільний для всіх сайтів, що вбудовують віджет, тому кожен запис зберігається окремо під origin хоста й віддається лише йому: ключ, збережений на site-a.com, недоступний для site-b.com.
  • У сховищі лежить шифротекст. Контейнер і його пароль запаковані в конверт AES-GCM-256, ключ шифрування — PBKDF2-SHA256 (310 000 ітерацій) з PIN-коду. Сам PIN ніде не зберігається.
  • Після введення PIN розшифрований конверт живе лише в пам'яті поточного екземпляра віджета — нова модалка попросить PIN знову. Якщо задано ttlMinutes, він переживає модалки в межах вкладки (sessionStorage) і гине разом із нею.
  • Термін зберігання ключа за замовчуванням — 30 днів, після чого запис видаляється сам.

Режим без PIN — і чому ми не радимо

Опцію треба спершу дозволити інтегратором (session: { noPin: true }) — лише тоді у віджеті з'явиться галочка «Не використовувати PIN». Якщо користувач її позначить, підпис іде одразу, без жодного введення. Віджет прямо попереджає, що це менш безпечно:

Без PIN ключ у сховищі захищений лише від інших сайтів. Будь-хто з доступом до цього комп'ютера й браузера зможе ним підписувати.

Технічно в цьому режимі конверт шифрується випадковим секретом, що лежить поруч у тому ж сховищі — це обфускація, а не захист. Використовуйте його лише на довірених робочих місцях.

Що варто зважити (чесно)

Автоматичний режим свідомо міняє частину безпеки на зручність:

  • Немає підтвердження кожного підпису. Поки сесія розблокована, ваш код може підписати будь-що без участі користувача. Якщо вашу сторінку скомпрометують (XSS), зловмисник зможе підписувати документи від імені користувача, доки триває сесія. Без збереженого ключа він мусив би знати пароль до контейнера.
  • Ключ лежить на диску користувача (зашифрований). Для звичайного режиму ключ узагалі не покидає оперативну пам'ять вкладки.

Тому:

  • функція вимкнена за замовчуванням — вмикайте свідомо й лише там, де вона справді потрібна;
  • не дозволяйте noPin без ваговитої причини: PIN — головний захист збереженого ключа;
  • ttlMinutes тримайте помірним (наприклад, тривалість одного сеансу роботи);
  • для критичних операцій (платежі, договори на великі суми) залишайте звичайний режим із підтвердженням;
  • давайте користувачу кнопку «Забути ключ» у своєму інтерфейсі — signer.session.forget().