В Казахстане опасно использовать ЭЦП
В последнее время государство пытается максимально перенести все госуслуги в электронный формат. Активно выдаются адресные справки, и другие справки выдаются через Портал электронного правительства. Даже можно зарегистрировать брак поженится через портал. На самом деле, очень удобно. Есть конечно же минусы, в основном — организационные, нормативные на уровне законов, на уровне реализации. Но это уже другой вопрос, главное очень хорошие начинания. Это все хорошо, но пост не про это.
Очевидно, чтобы пользоваться госуслугами, нужно как-то подтверждать свою личность. Для этого когда-то давно законодательно закрепили использование ЭЦП. Основная формулировка применения ЭЦП такая — ЭЦП приравнивается к собственноручной подписи. Многие не знают, но за передачу ключей ЭЦП (здесь и далее буду использовать термин — ключи ЭЦП. Все называют просто ЭЦП, а по факту это две пары ключей — для аутентификации и подписи). За передачу третьим лицам даже есть какая-то ответственность. Очевидно, что многим людям это без разницы, не понимают всей серьезности.
Вообще тема поста про NCALayer, прослойка между браузером и ключами ЭЦП. По безопасности — это уязвимый механизм использования ЭЦП.
Что такое NCALayer
Так как основная реализация криптопровайдера на Java и в последних версиях браузеров нет возможности использовать аплеты, то НУЦ придумал оригинальное решение для использования ЭЦП в браузерах. Это решение называется — NCALayer. NCALayer — посредник между браузером, криптопровайдером и ключами ЭЦП.
NCALayer устанавливается локально на компьютере пользователя. Работает NCALayer следующим образом — открывается вебсокет сервер на определенном порту, куда отправляется разного рода запросы.
Опуская все детали подключения, рассмотрим пока два запроса, чтобы иметь общее представление как NCALayer работает:
- Выбрать ключ на файловой системе.
{ '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
- Здесь один большой минус — путь к файлу и паролю доступен любому разработчику сайта, где используется ЭЦП. Даже пользуясь всякими токенами, при использовании NCALayer, пароль от устройства-токена также передаются на сайт. По крайней мере, текущая реализация позволяет это сделать.
- Хранение путей к ключам и пароль каждый сайт может хранить у себя в базе. Может и не хранить. Вообще, хранить или же не хранить пути и пароли — опять же, все это лежит на совести разработчиков сайтов.
- Любой сайт может за вас подписывать данные без вашего ведома в фоновом режиме, если он знает про путь где хранятся ключи и пароль. Опять таки, Если вы хоть раз использовали ЭЦП на сайте, то сайт уже знает путь к файлу и паролю. Если сайт-злоумышленник, то он гарантированно сохранит пароль где-то у себя.
- Хочу заметить, что прямой доступ к носителю с ключами не предоставляется. Доступ ограничен только функциями NCALayer.
Реальный пример, как получить доступ к egov.kz, если ты не владеешь ЭЦП человека
Не буду углубляться глубоко в технические детали и реализацию. Опишу как можно это сделать.
Теперь, чтобы эту уязвимость эксплуатировать, нужно понимать как работаем механизм входа на egov.kz через ЭЦП. Для входа на egov.kz, xml от egov.kz подписывается пользователем и передается на сервер, где проверяется. Если подпись валидна, то осуществляется вход. Со стороны NCALayer, процесс входа состоит из следующих шагов:
Портал запрашивает следующие данные из NCALayer — loadSlotList (здесь можно ответить ошибкой), getKeys, getSubjectDN, getNotBefore, getNotAfter и signXml. Если NCALayer правильно подставит эти данные от другого пользователя, то соответственно мы удачно войдем в систему. Здесь очень важно правильно получить от NCALayer только subjectDN и xml для подписи.
Теперь как получить доступ к egov.kz от другого человека, механизм:- У себя на компьютере, извлекаешь xml строку, которую нужно подписать чтобы войти на egov.kz. Это делается так, просто в консоли разработчика на idp.egov.kz, нужно запросить следующие данные —
document.getElementById('xmlToSign').value
. - Отправляешь xml строку на подпись нужному человеку, который сидит на сайте-злоумышленнике. Он у себя на компьютере, в фоновом режиме подписывает нужную xml строку. Дополнительно получаешь subjectDN.
- Сейчас в наличии есть subjectDN и подписанный xml.
- Теперь самое интересное, у себя на компьютере эмулируешь работу NCALayer, который отдает необходимые данные.
Некоторые утверждения
- Пост не рассчитан на широкую аудиторию, больше на технарей, которые понимают принципы веб-разработки.
- Уязвимы ВСЕ ресурсы, которые используют NCALayer.
- Познания в криптографии не нужны.
- Для эксплуатации этой уязвимости не нужно получать SDK от НУЦ. Соответственно, НУЦ не в состоянии выявить сайты-злоумышленники.
- Разработчики NCALayer не могут дать гарантии, что злоумышленники не смогут использовать такой механизм. Это будет глупо отвечать за всех. Технически возможность есть.
- Уязвимы ключи не только на файловой системе, но также на токенах.
- Вы гарантированно засветили пароль от носителя ключей ЭЦП, даже от токенов. Достаточно войти всего один раз на egov.kz. Как используется пароль на сайте, это на совести разработчиков.
- Насколько я слышал, уже есть системы, которые хранят путь к ключам ЭЦП и пароль в настройках.
- На сайтах нет уязвимостей, просто схема использования ЭЦП через NCALayer небезопасна.
Update:
Что можно сделать
- Будет неудобно —, но при каждом использовании ключей, запрашивать хотя бы пароль.
- Продвигать web crypto api
- …
Эмулятор NCALayer — https://github.com/maratkalibek/digisign-layer-emulator
Приложение, которое без ведома пользователя, в фоновом режиме подписывает данные — https://github.com/maratkalibek/background-signer