ЕЦП у браузері проблеми, рішення, особистий досвід

проблеми

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

Насправді сьогодні ситуація з ЕЦП у браузері все ж таки не так сумна як ще кілька років тому, але вона все ж таки далека від ідеалу. Ця тема також кілька разів піднімалася на хабрі, наприклад, тут і тут.

Під катом розповідь про саму проблему, про те, як цю проблему можна вирішити, про те, як я її вирішував, а також особисті враження про те, як справи з ЕЦП у Білорусі.

Суть проблеми та що з нею буде завтра

Проблема досить тривіальна: хочете реалізувати ЕЦП на клієнті у браузері, думаєте використати для цього свій улюблений javascript? Нічого не вийде, і все тому, що браузери просто не надають API для роботи із сертифікатами, токенами, підписом тощо. і тп… Як має виглядати цей механізм у мріях будь-якого веб-розробника? Напевно якось так:

Так, а ще було б чудово, щоб усе це підтримувало вітчизняні ГОСТи… ну, це я вже зовсім розмріявся. На жаль, нічого подібного у сучасних браузерах ви не знайдете. Є, звичайно, боязкі спроби реалізувати щось схоже у Mozilla, але попередження в заголовку статті дуже засмучує:

До речі, якщо хтось намагався використати цей API, відпишіться дуже цікаво. Також є згадка Crypto у репозиторії W3C. Швидше за все робота там почалася зовсім не так давно, матеріалу там зараз небагато, але останнєоновлення було нещодавно, так що робота йде:

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

Хочу відразу обмовитися, ЕЦП у браузері — це, мабуть, один із небагатьох випадків, коли розробник просто змушений використовувати різні хитрощі та милиці, я перерахую найпопулярніші з них:

  • використання ActiveX (CAPICOM)
  • використання плагінів до браузерів
  • використання Java-аплетів
  • використання тунелю (Stunnel)

Давайте розглянемо недоліки кожного з них, гідності описувати не буду, імхо, у всіх милиць воно одне - "ну, воно ж працює".

Використовується в 99% випадків, коли необхідно реалізувати ЕЦП у браузері, не соромляться використовувати банки, торгові майданчики та інші серйозні організації. На мій погляд, зараз це найгірший варіант, чому? Ви звикли використовувати свій улюблений FF чи Chrome? - Забудьте! ActiveX працює тільки в IE. Не любите копатися в налаштуваннях браузеру? - А доведеться! Перед тим як все запрацює, вам неабияк доведеться покопатися в налаштуваннях безпеки вашого IE. А може бути ви такий просунутий, що у вас стоїть Win7, та ще й x64, а може ви ще й IE9-10 собі поставили? — Дуже дарма, швидше за все, у вас нічого не вийде. Жарти жартами, адже Microsoft оголосила, що підтримка CAPICOM припинена і далі компонент розроблятися не буде і остання версія CAPICOM, яка офіційно підтримується, була у Windows Vista.

Плагіни до браузерів
Java applet

Все начебто не так вже й погано, і код написаний один раз, і працює у всіх браузерах, і навіть налаштовувати нічогоне треба. Але якщо у вас не встановлено JRE, нічого не буде. Найчастіше працює у зв'язці з OpenSSL, хоча, використовуючи JNI, можна багато чого прикрутити. Так, щоб усе працювало, сам аплет має бути підписаний.

Відносно новий спосіб працює за принципом проксі, основна ідея в тому, що особливим чином сформований POST-запит при відправці на сервер проходить через тунель, той підписує дані з цього запиту, підставляє підписані дані в полі запиту замість даних і все відправляється далі на сервер і туди вже надходять дані з ЕЦП. Принцип досить простий, але ефективний. У цього методу є практична реалізація. Докладніше можна почитати тут. Щоб все це працювало, на клієнті власне має бути встановлений цей тунель, хоча можна запустити і з флешки.

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

Особистий досвід

Так, мені теж "пощастило" займатися реалізацією ЕЦП у браузері. Сам я працюю в одній мінській компанії, що займається біржовою торгівлею, і одного разу знадобилося терміново реалізувати підтримку ЕЦП у браузері в одній із торгових систем. Скажу чесно, спочатку хотів зробити як і 99% у такій ситуації та задіяти ActiveX. Але поступово занурюючись у проблему, став усвідомлювати, що це обернеться спочатку головним болем для користувачів, а потім і для мене як розробника. Писати плагіни під кожний браузер не було часу. Залишалося два рішення: java аплет та тунель. Вирішальним тут виявився ... ви не повірите, ГОСТ.

Справа в тому, що в Білорусі як і в Україні прийнято свій ГОСТ напроцедури вироблення та перевірки електронного цифрового підпису, тільки у нас він називається СТБ РБ 1176.2–99 та ніяких вам RSA. Даєш свій ГОСТ кожній країні! І якщо для українського ГОСТу є практичні реалізації кожного з перерахованих вище способів, можна обирати будь-який, то білоукраїнським розробникам пощастило набагато менше. З цього приводу навіть особисто розмовляв із представниками компанії, яка випускає криптографічне програмне забезпечення для нашої країни. Розмова залишила двояке враження. Народ цілком адекватний, проблему розуміють, але кажуть, що це не їхнє завдання, вони, мовляв, написали криптопровайдер, який задовольняє всім ДСТУ і пройшов державну експертизу, а як ви його збираєтеся використати, це не їхня проблема.

— Можемо лише запропонувати використовувати ActiveX. — Ну, а як же проблеми пов'язані з ним? — У нас, звичайно, є певні напрацювання з використанням java аплетів, але як продукт ми вам їх поки що запропонувати не можемо. Розробка такого роду програмного забезпечення — не наше завдання.

На мою думку, це не зовсім правильна позиція, адже пропонуючи продукт, комерційно вигідно запропонувати і оточення до нього.

Ну та гаразд, працюємо з тим, що є. А що маємо? Раніше в нашій компанії вже був написаний desktop-ий додаток, що використовує функції ЕЦП, і там був компонент, що працює безпосередньо з CryptoAPI, написаний він був на delphi. Дуже хотілося якось використати цей досвід колег і самому не витрачати на цей час, а найголовніше зробити це швидко. Але як це зробити? З'єднати компонент на delphi та веб-додаток? Відповідь на схемі:

проблеми

Коротко поясню, що відбувається. Коли нам потрібно щось підписати, ми за допомогою javascript викликаємо функцію java аплету:

Аплет у свою чергу через сокети зв'язується з desktop-додатком, передає йому необхідні параметри, додаток підписує те, що ми запросили (для цього використовується раніше написаний компонент колег), і передає підписані дані аплету, а той у свою чергу браузеру, викликаючи функцію:

Сподіваюся, що викладена інформація допоможе краще розібратися з проблемою ЕЦП у браузері тим, хто з нею зіткнувся.