Авторизация через ЭЦП с использованием NCLayer

Цель: Обеспечение безопасности авторизации юридических лиц с использованием ЭЦП.
Метод авторизации: Пользователи выбирают свой ЭЦП-ключ и вводят пароль.

Последовательность действий:

  1. Пользователь выбирает из списка свой ЭЦП и вводит пароль на фронте для авторизации.
  2. Данные отправляются для обработки в NCLayer через API.
  3. Возвращенный результат NCLayer подтверждает или отклоняет авторизацию.

Возникли сомнения в понимании того как я должен организовать взаимодействие бэка с фронтом. Я думаю, что есть возможность подмены данных при авторизации через ЭЦП. У меня опасение, что злоумышленник может изменить данные в процессе передачи с фронта в NCLayer, тем самым получив несанкционированный доступ.

Вопрос:
Как правильно осуществлять проверку сертификата? Я ознакомился с примерами использования ЭЦП, простите все равно не понимаю как правильно организовать авторизацию. Прошу вас на словах подсказать как это сделать?

Одно из возможных решений это дать пользователю на подпись какие-либо данные (UUID например). На стороне бэка вам нужно будет валидировать подпись и при успешной валидации авторизовать пользователя. Если злоумышленник передаст другие данные в NCALayer, то он от этого ничего не выиграет потому что вы проверите подпись.

Я не понял что вы имеете ввиду.
Поправьте меня, если я не правильно вас понял.

Если ИИН резолвится на фронте каким образом проверка сгенерированного на бэкэнде UUID поможет проверить достоверность этого ИИНа?

Вы можете выдать любые уникальные данные на подпись пользователю, это не обязательно должен быть UUID. Главное убедиться при валидации что подписаны были именно те данные, которые вы оправили. Если пользователь каким-то образом подпишет другие данные, то подпись не пройдет валидацию.

ИИН вы извлекаете из сертификата из подписи при проверке на бэке, а не на фронте.

Спасибо большое вам за ответы!
Каким образом я могу из ЭЦП вытащить данные ИИН/БИН, ФИО? Я не понимаю этого из документации.

Эти данные есть в сертификате.

Простите за глупые возможно вопросы. Как их получить из сертификата, когда пользователь выбирает его при авторизации? Какой метод необходидимо использовать или если не сложно можете описать методы?

Сертификат вы извлекаете из подписи на стороне бэка. Примеры есть в SDK.

Тут знаете как из рассказа в школе: смотрю в книгу, вижу ф…
Я не понимаю какой файл смотреть и какую строку, можете подсказать пожалуйста? :raised_hands::pray:
Пишу на .net

По пути SDK 2.0\COM_Windows\examples\KalkanCryptTest_CSharp есть пример на С#.

Добрый день,

Есть статья с описанием процесса: Аутентификация по цифровым сертификатам.

Добрый вечер! Получаю 2 разных значения в поле keyUsage.

  1. keyUsage=digitalSignature keyEncipherment (ключ авторизации)
  2. keyUsage=digitalSignature nonRepudiation (RSA)

Корректно ли использовать данные значения keyUsage для того чтобы отличать типы сертификатов? Дословно: я если получил nonRepudiation, то он для подписи. Если я получил keyEncipherment, то для авторизации.

Верно, коллеги?
Спасибо большое за ответ.
Напомню, что задача заключается подключить авторизацию на сайте.

@SAAAAAAM @Daniyar простите за назойливость и здравствуйте! Я буду очень благодарен за консультацию по вопросу выше :pray:

Да, верно. Расширение “Использование ключа” для аутентификации имеет значение “Цифровая подпись, Шифрование ключей”, а для подписи “Цифровая подпись, Неотрекаемость”. Однако в сертфикатах нового образца для ключей по новому ГОСТ-у будут все 3 значения.

@SAAAAAAM Салют! Спасибо вам за информацию, надеюсь, что эта информация в том числе будет полезной и для других участников форума.

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

Можете, пожалуйста, направить куда нужно смотреть? Может быть подскажете название функции, если таковые имеются в примерах на C.

С началом новой недели вас коллеги! Надеюсь у вас все хорошо и я очень буду рад видеть ответ на форуме) @Daniyar или @SAAAAAAM

Добрый день! Спасибо за пожелания и Вам тоже!

В библиотеках НУЦ нет функции дешифрования/шифрования. Библиотеки работает только с ЭЦП. Или что Вы понимаете под дешифровать хэш сообщения? Хэш сообщения не дешифруется. Его можно проверять на равенство с другим вычисленным хэш. В SDK есть метод для вычисления хэш. С и COM библиотеках этот метод называется HashData.

@Daniyar

Вопросы про дешифрование возник при прочтении пункта 5.1(глава №2)(https://pki.gov.kz/docs/razrabotka/pravila_proverki.pdf)

  1. Проверка ЭЦП осуществляется в обратном порядке, по которому производилась
    подпись документа, по следующей схеме:
  1. с помощью открытого ключа ЭЦП отправителя дешифруется хэш сообщения (
    подпись отправителя);
  2. с помощью хэш-функции вычисляется контрольная сумма оригинального
    сообщения.
    На данном этапе производится сверка двух контрольных сумм, если они равны, то
    ЭЦП считается верной (определен положительный результат проверки ЭЦП), если не
    равны, то ЭЦП считается не действительной (определен отрицательный результат
    проверки ЭЦП).

В случае если не надо производить дешифрацию, как и где найти хэш подписанного сообщения(какое поле и какая функция за это отвечает?)

В голове я представляю такой путь, который надо реализовать для авторизации по ЭЦП:

  • фронтенд формирует запрос на бекенд для получения блока случайных чисел
  • бекенд возращает блок случайных чисел на подпись
  • фронтенд подписывает блок случайных чисел(посредством ncalayer), далее шлет подпись на бекенд
  • бекенд получает подпись, получает ИИН / БИН клиента из сертфикиката клиента, каким-то образом получает хэш сообщения, формирует оригинальное сообщение(ранее выданный блок случайных чисел) и вычисляет хэш оригинального сообщения.
    В случае равенства данных хэшей и актуальности блока случайных чисел, выдает токен пользователю(по которому далее клиент будет ходить в ИС)

Я понял что, нужно воспользоваться функцией hashdata, чтобы получить хэш оригинального сообщения (без подписей, просто как есть), но вот как найти другой хэш, с которым надо произвести сравнение - пока не понятно.

Thanks

Тут имеется в виду, что с помощью открытого ключа ЭЦП из значения подписи получаем хэш. Значения подписи представляет из себя набор символов. Где взять этот набор символов зависит от формата сформированной подписи. В библиотеке нет такого внешнего метода. Но, Вам не придется все это делать вручную самому. Есть готовые методы в библиотеке, где все эти проверки делаются внутри, и на выходе получаем результат об успешности проверки.

@Daniyar

Иными словами метод VerifyData из kalkan производит необходимую проверку?
Смутило, что метод не принимает оригинальное сообщение, для сверки хэша оригинального сообщения с тем, что было подписано.
Возможно оригинальное сообщение уже содержится в формате base64 (мое предположение) в ПОДПИСИ, тем самым обеспечивается равность хешей.

Можно переформулировать так: Метод VerifyData обеспечивает проверку пункта №5(проверка ЭЦП в электронном документе)?

Если дело обстоит так, то все становится понятно и все что нужно сделать это раскодировать сообщение из BASE64 и получить оригинальное сообщение.