Как стать автором
Обновить

Принудительно добавляем поддержку защищенных носителей (токенов и карт) в недоработанные порталы Республики Казахстан

Время на прочтение4 мин
Количество просмотров2K

В Казахстане многие информационные системы не корректно интегрированы с NCALayer и в результате поддерживают только файловые хранилища ключей ЭЦП (читателям, интересующимся примерами таких сервисов, рекомендую изучить цикл статей Доска почёта ЭЦП посвященный анализу проблем с реализацией поддержки ЭЦП в информационных системах). Тех, кто предпочитает пользоваться защищенными носителями (картами и токенами, НУЦ поддерживает несколько: https://pki.gov.kz/docs/nl_ru/smartcards/), это сильно раздражает, так как им приходится выпускать временные сертификаты на файловую систему для того, чтобы работать с такими порталами. Для меня последней каплей стало то, что в недавно переработанной системе https://hr.enbek.kz (государственная система регистрации и учета трудовых договор) поддержка защищенных носителей так и не была реализована.

В этой заметке я расскажу как технически подкованные пользователи могут обходить ограничения в поддержке носителей путем запуска локального прокси и модификации отправляемых в NCALayer команд на лету.

Теория

Информационные системы на базе веб технологий взаимодействуют с NCALayer по WebSocket с помощью сообщений в формате JSON. Ознакомиться с командами можно в интерактивной документации по приложению KAZTOKEN mobile (либо можно получить SDK НУЦ, но, к сожалению, там есть только примеры). Поддержка защищенных носителей сводится к тому, что нужно:

  1. отправить kz.gov.pki.knca.commonUtils.getActiveTokens, в ответ получить список типов хранилищ, экземпляры которых в данный момент доступны для использования;

  2. в том случае, если список не пуст, определить (к примеру спросить у пользователя) какой тип использовать;

  3. передавать в последующие команды тип хранилища.

Разработчики некоторых информационных систем халтурят, пропускают первые два пункта и далее всегда передают константу "PKCS12", то есть файловое хранилище. Это приводит к тому, что пользователь не может воспользоваться ключами ЭЦП на защищенном носителе, а таких пользователей, судя по статистике НУЦ РК, довольно много:

Более того, в руководстве по получению сертификатов НУЦ РК явно рекомендуется использовать защищенные носители:

Внимание! Хранилище «Персональный компьютер» является небезопасным. Рекомендуем использовать защищенный носитель ключевой информации для снижения риска компрометации ключей ЭЦП.

Таким образом для того, чтобы заставить не качественно разработанный портал поддерживать защищенные носители, нужно в сообщениях, отправляемых из JS кода этого портала в сторону NCALayer, заменять подстроку "PKCS12" на константу интересующего носителя. Я пользуюсь устройствами KAZTOKEN, поэтому буду подставлять константу "AKKaztokenStore".

Практика

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

Для модификации команд на лету я воспользуюсь утилитой mitmproxy.

Модификацию будет выполнять следующий скрипт (KAZTOKENify.py, за основу взят https://github.com/mitmproxy/mitmproxy/blob/main/examples/addons/websocket-simple.py):

import re
from mitmproxy import ctx, http

def websocket_message(flow: http.HTTPFlow):
    assert flow.websocket is not None
    message = flow.websocket.messages[-1]
    if message.from_client:
        message.content = re.sub(rb"PKCS12", b"AKKaztokenStore", message.content)

Для выборочного использования прокси буду использовать файл следующий автоматической настройки прокси (Proxy Auto-Configuration (PAC)) proxy.pac:

function FindProxyForURL(url, host) {
  if (url.indexOf('wss://127.0.0.1:13579') == 0 || url.indexOf('wss://localhost:13579') == 0 || 
    url.indexOf('https://127.0.0.1:13579') == 0 || url.indexOf('https://localhost:13579') == 0 ||
    url.indexOf('http://mitm.it') == 0) {
    return "PROXY 127.0.0.1:8080";
  }

  return "DIRECT";
}

Для настройки нужно выполнить шаги:

  1. Скачать сборку mitmproxy для своей ОС, распаковать архив.

  2. Создать текстовый файл KAZTOKENify.py в папке с утилитой mitmproxy, вставить в него скрипт.

  3. Запустить mitmproxy --allow-hosts 127.0.0.1 --allow-hosts localhost --ssl-insecure --scripts KAZTOKENify.py (прокси будет вскрывать только трафик на 127.0.0.1 и localhost, а так же не будет проверять TLS сертификат сервера, это проще чем настраивать доверие к сертификату NCALayer).

  4. Создать текстовый файл proxy.pac, вставить в него соответствующий код.

  5. В браузере открыть Настройки -> Параметры сети -> Настроить…, выбрать URL автоматической настройки прокси и указать путь к файлу proxy.pac в следующем виде: file:///home/user/folder/proxy.pac.

  6. В браузере открыть about:config и установить network.proxy.allow_hijacking_localhost в true (иначе Firefox не будет использовать прокси для 127.0.0.1 и localhost).

  7. В браузере открыть http://mitm.it/, установить сертификат УЦ mitmproxy (сертификат УЦ генерируется на каждом ПК свой в отличие от NCALayer, который требует от всех доверять одному сертификату).

  8. В браузере открыть https://127.0.0.1:13579, удостовериться в том, что браузер видит NCALayer в соответствии с инструкцией (для TLS будут использоваться сертификаты УЦ mitmproxy).

Готово, теперь можно пройти на https://hr.enbek.kz и подписать что-нибудь, NCALayer будет отображать интерфейс работы с устройствами KAZTOKEN, а не с файловой системой.

Либо можно попробовать на странице интерактивной документации KAZTOKEN mobile. Для этого, к примеру, можно выбрать kz.gov.pki.knca.commonUtils.getKeyInfo, заменить в ней AKKaztokenStore на PKCS12 и отправить, NCALayer все равно будет работать с KAZTOKEN.

Заключение

Буду очень признателен каждому читателю, который расскажет своему знакомому разработчику о том, что НУЦ выпускает сертификаты не только на файловую систему!

А разработчикам рекомендую использовать JS библиотеку ncalayer-js-client в надежде на то, что более простой инструмент для работы с NCALayer оставит больше времени и сил на проработку нюансов интеграции.

История изменений

2022.08.20 - доработан proxy.pac чтобы корректно отображался http://mitm.it/.

Теги:
Хабы:
+7
Комментарии4

Публикации