В Казахстане опасно использовать ЭЦП

В последнее время государство пытается максимально перенести все госуслуги в электронный формат. Активно выдаются адресные справки, и другие справки выдаются через Портал электронного правительства. Даже можно зарегистрировать брак поженится через портал. На самом деле, очень удобно. Есть конечно же минусы, в основном — организационные, нормативные на уровне законов, на уровне реализации. Но это уже другой вопрос, главное очень хорошие начинания. Это все хорошо, но пост не про это.


Очевидно, чтобы пользоваться госуслугами, нужно как-то подтверждать свою личность. Для этого когда-то давно законодательно закрепили использование ЭЦП. Основная формулировка применения ЭЦП такая — ЭЦП приравнивается к собственноручной подписи. Многие не знают, но за передачу ключей ЭЦП (здесь и далее буду использовать термин — ключи ЭЦП. Все называют просто ЭЦП, а по факту это две пары ключей — для аутентификации и подписи). За передачу третьим лицам даже есть какая-то ответственность. Очевидно, что многим людям это без разницы, не понимают всей серьезности.


Вообще тема поста про NCALayer, прослойка между браузером и ключами ЭЦП. По безопасности — это уязвимый механизм использования ЭЦП.


Что такое NCALayer


Так как основная реализация криптопровайдера на Java и в последних версиях браузеров нет возможности использовать аплеты, то НУЦ придумал оригинальное решение для использования ЭЦП в браузерах. Это решение называется — NCALayer. NCALayer — посредник между браузером, криптопровайдером и ключами ЭЦП.
NCALayer устанавливается локально на компьютере пользователя. Работает NCALayer следующим образом — открывается вебсокет сервер на определенном порту, куда отправляется разного рода запросы.
Опуская все детали подключения, рассмотрим пока два запроса, чтобы иметь общее представление как NCALayer работает:


  1. Выбрать ключ на файловой системе.
    {
    'method': "browseKeyStore",
    'args': ['PKCS12', 'P12', '/home/user']
    }

    После отправки запроса, на машине где стоит NCALayer, открывается диалоговое окно, которое предлагает выбрать файл ключей ЭЦП.
    Соответственно, после выбора ключа, через сокет получаем следующий ответ.

    {"result":"/home/user/AUTH_RSA.p12","errorCode":"NONE"}
    {"errorCode":"NONE"}

    Внимание: при использовании NCALayer, получаешь реальный путь к файлу на машине клиента.


    Если у вас есть путь к хранилищу ключей, то для последующей работы обязательно нужно предоставлять пароль от этого хранилища. Обычно сайт как-то забирает этот пароль через формочку. Вот пример, как подписать или поставить ЭЦП на какие-нибудь данные.
    {
    "method": "signXml",
    "args": [
      'PKCS12',
      '/home/user/AUTH_RSA.p12',
      '1874abcef234',
      'ПАРОЛЬ!!!',
      '1517997213006'
    ]
    }

    Не буду публиковать ответ, но там содержится подписанная часть xml, которая была в запросе.
    Повторюсь, получить пароль от хранилища ключей ЭЦП, ложится на плечи сайта. То есть, сайт всегда знает где лежат ключи и пароль у пользователя, иначе работать нельзя.

    Минусы реализации текущего варианта NCALayer


    1. Здесь один большой минус — путь к файлу и паролю доступен любому разработчику сайта, где используется ЭЦП. Даже пользуясь всякими токенами, при использовании NCALayer, пароль от устройства-токена также передаются на сайт. По крайней мере, текущая реализация позволяет это сделать.
    2. Хранение путей к ключам и пароль каждый сайт может хранить у себя в базе. Может и не хранить. Вообще, хранить или же не хранить пути и пароли — опять же, все это лежит на совести разработчиков сайтов.
    3. Любой сайт может за вас подписывать данные без вашего ведома в фоновом режиме, если он знает про путь где хранятся ключи и пароль. Опять таки, Если вы хоть раз использовали ЭЦП на сайте, то сайт уже знает путь к файлу и паролю. Если сайт-злоумышленник, то он гарантированно сохранит пароль где-то у себя.
    4. Хочу заметить, что прямой доступ к носителю с ключами не предоставляется. Доступ ограничен только функциями NCALayer.

    Реальный пример, как получить доступ к egov.kz, если ты не владеешь ЭЦП человека


    Не буду углубляться глубоко в технические детали и реализацию. Опишу как можно это сделать.
    Теперь, чтобы эту уязвимость эксплуатировать, нужно понимать как работаем механизм входа на egov.kz через ЭЦП. Для входа на egov.kz, xml от egov.kz подписывается пользователем и передается на сервер, где проверяется. Если подпись валидна, то осуществляется вход. Со стороны NCALayer, процесс входа состоит из следующих шагов:
    ba5ykhvvvtwcsocrhgq16sfejfa.png
    Портал запрашивает следующие данные из NCALayer — loadSlotList (здесь можно ответить ошибкой), getKeys, getSubjectDN, getNotBefore, getNotAfter и signXml. Если NCALayer правильно подставит эти данные от другого пользователя, то соответственно мы удачно войдем в систему. Здесь очень важно правильно получить от NCALayer только subjectDN и xml для подписи.
    Теперь как получить доступ к egov.kz от другого человека, механизм:


    1. У себя на компьютере, извлекаешь xml строку, которую нужно подписать чтобы войти на egov.kz. Это делается так, просто в консоли разработчика на idp.egov.kz, нужно запросить следующие данные — document.getElementById('xmlToSign').value.
    2. Отправляешь xml строку на подпись нужному человеку, который сидит на сайте-злоумышленнике. Он у себя на компьютере, в фоновом режиме подписывает нужную xml строку. Дополнительно получаешь subjectDN.
    3. Сейчас в наличии есть subjectDN и подписанный xml.
    4. Теперь самое интересное, у себя на компьютере эмулируешь работу NCALayer, который отдает необходимые данные.

    Некоторые утверждения


    1. Пост не рассчитан на широкую аудиторию, больше на технарей, которые понимают принципы веб-разработки.
    2. Уязвимы ВСЕ ресурсы, которые используют NCALayer.
    3. Познания в криптографии не нужны.
    4. Для эксплуатации этой уязвимости не нужно получать SDK от НУЦ. Соответственно, НУЦ не в состоянии выявить сайты-злоумышленники.
    5. Разработчики NCALayer не могут дать гарантии, что злоумышленники не смогут использовать такой механизм. Это будет глупо отвечать за всех. Технически возможность есть.
    6. Уязвимы ключи не только на файловой системе, но также на токенах.
    7. Вы гарантированно засветили пароль от носителя ключей ЭЦП, даже от токенов. Достаточно войти всего один раз на egov.kz. Как используется пароль на сайте, это на совести разработчиков.
    8. Насколько я слышал, уже есть системы, которые хранят путь к ключам ЭЦП и пароль в настройках.
    9. На сайтах нет уязвимостей, просто схема использования ЭЦП через NCALayer небезопасна.

    Update:


    Что можно сделать


    1. Будет неудобно —, но при каждом использовании ключей, запрашивать хотя бы пароль.
    2. Продвигать web crypto api


    Эмулятор NCALayer — https://github.com/maratkalibek/digisign-layer-emulator
    Приложение, которое без ведома пользователя, в фоновом режиме подписывает данные — https://github.com/maratkalibek/background-signer

© Habrahabr.ru