Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

  • пользовательские (константа в плагине CERT_CATEGORY_USER)
    Это сертификаты, связанные с закрытым ключом пользователя. Применяются, например, для подписи CMS/PKCS#7, аутентификации пользователя в протоколе TLS.
    Если сертификат импортируется как пользовательский, то при импорте будет произведен поиск в устройстве соответствующего ему закрытого ключа. Если такой ключ будет найден, то сертификат будет «привязан» к этому ключу. Если ключ найден не будет, то вернется ошибка.
  • корневые (константа в плагине CERT_CATEGORY_CA)
    Это сертификаты издателей сертификатов, применяющиеся для проверки подписи под сертификатами. Подобная проверка подписи (построение цепочки доверия) позволяет определить, доверяет ли пользователь подписи другого пользователя. Например, в функции плагина verify есть режим проверки сертификата, на котором было подписано сообщение. При этом используется хранилище корневых сертификатов на токене, созданное импортом корневых сертификатов на токен.
  • другие (константа в плагине CERT_CATEGORY_OTHER)
    Это сертификаты, которые не связаны с закрытым ключом и не являются корневыми.

...

4. Сертификат можно распарсить вызовом функции parseCertificate и получить из него DN Subject, DN Issuer, расширения, значение открытого ключа, подпись, серийный номер, срок действия и т.п.

5. Сертификат можно записать на устройство.

Code Block
languagejs
titleПример записи сертификата на устройство как пользовательского:
 var certpem = "-----BEGIN CERTIFICATE-----
MIIBmjCCAUegAwIBAgIBATAKBgYqhQMCAgMFADBUMQswCQYDVQQGEwJSVTEPMA0G
A1UEBxMGTW9zY293MSIwIAYDVQQKFBlPT08gIkdhcmFudC1QYXJrLVRlbGVjb20i
MRAwDgYDVQQDEwdUZXN0IENBMB4XDTE0MTIyMjE2NTEyNVoXDTE1MTIyMjE2NTEy
NVowEDEOMAwGA1UEAxMFZmZmZmYwYzAcBgYqhQMCAhMwEgYHKoUDAgIjAQYHKoUD
AgIeAQNDAARADKA/O1Zw50PzMpcNkWnW39mAJcTehAhkQ2Vg7bHkIwIdf7zPe2Px
HyAr6lH+stqdACK6sFYmkZ58cBjzL0WBwaNEMEIwJQYDVR0lBB4wHAYIKwYBBQUH
AwIGCCsGAQUFBwMEBgYpAQEBAQIwCwYDVR0PBAQDAgKkMAwGA1UdEwEB/wQCMAAw
CgYGKoUDAgIDBQADQQD5TY55KbwADGKJRK+bwCGZw24sdIyayIX5dn9hrKkNrZsW
detWY3KJFylSulykS/dfJ871IT+8dXPU5A7WqG4+
-----END CERTIFICATE-----";

try
{   
    plugin.importCertificate(deviceId, certpem, plugin.CERT_CATEGORY_USER);
}
catch (error) 
{
    console.log(error);
}

6. Вызовом функции deleteCertificate можно удалить сертификат с токена.

...


2. Для генерации ключевой пары требуется ввод PIN-кода. При генерации ключа параметры могут быть выбраны из набора:

  • A: id-GostR3410-2001-CryptoPro-A-ParamSet
  • B: id-GostR3410-2001-CryptoPro-B-ParamSet
  • C: id-GostR3410-2001-CryptoPro-C-ParamSet
  • XA: id-GostR3410-2001-CryptoPro-XchA-ParamSet
  • XB: id-GostR3410-2001-CryptoPro-XchB-ParamSet

можно задать параметры ключевой пары. Если опция не задана, будут выбраны параметры А для любого из алгоритмов ГОСТ.

  • ГОСТ Р 34.10-2012 длина закрытого ключа 256 бит: 
    • "A"
    • "B"
    • "C"
    • "XA"
    • "XB"
  • ГОСТ Р 34.10-2012 длина закрытого ключа 512 бит
    • "A"
    • "B"


Code Block
languagejs
Code Block
languagejs
titleПример генерации ключевой пары ГОСТ Р 34.10-20012012:
var options = {};
var keyId;

try 
{
    keyId = plugin.generateKeyPair(deviceId, "A"undefined,  nullmarker, options);
}
catch (error) 
{
    console.log(error);
}

3. С помощью функции deleteKeyPair ключевая пара может быть удалена с токена.

Конфигурирование openssl

...


См. инструкцию Интеграция ГОСТ 2012 с Рутокен ЭЦП и OpenSSL 1.1.0 или новее, раздел Установка и настройка OpenSSL

Code Block
[openssl_def]
engines = engine_section

[engine_section]
gost = gost_section

[gost_section]
engine_id = gost
default_algorithms = ALL

Если конфигурационный файл openssl не расположен в стандартном месте, то путь к нему можно задать через переменную окружения OPENSSL_CONF. 

 Другим вариантом подгрузки engine gost является ее передача в параметрах командной строки утилиты openssl.
Если engine gost не расположена в стандартном месте, то через переменную окружения OPENSSL_ENGINES можно задать путь к директории, в которой openssl будет ее искать.
Для получения информации о том, успешен ли был вызов утилиты openssl или нет, с возможностью уточнения ошибки, требуется парсить stdout и stderror. В конце статьи приведена ссылка на PHP-скрипт, который использует данную утилиту.


Теперь перейдем к реализации законченных пользовательских сценариев.

...

  • Получаем список подключенных к компьютеру устройств Рутокен ЭЦП
  • Генерируем ключевую пару по ГОСТ Р 34.10-2001 2012 на выбранном Рутокен ЭЦП
  • Cоздаем запрос PKCS#10 на сертификат для сгенерированной ключевой пары
  • Отправляем запрос на сервер
  • На сервере создаем сертификат, привязываем к аккаунту (сам сертификат или его дескриптор). Следует отметить, что дескрипторы сертификатов, полученные при вызове функции enumerateCertificates, являются уникальными и неизменными
  • Отправляем сертификат на клиент
  • На клиенте визуализируем полученный сертификат
  • Импортируем полученный сертификат в Рутокен ЭЦП

...

Code Block
languagebash
openssl genpkey -engine gost -algorithm GOST2001gost2012_256 -pkeyopt paramset:A -out ca.key

...

Code Block
languagebash
openssl req -engine gostutf8 -x509 -new -key caseckey.keypem -out ca.crt

После ввода необходимой информации об издателе в файле ca.crt будет создан сертификат УЦ.

Полученный от клиента запрос сохраняем в файл user.csr и выдаем на его основе сертификат (без модификации данных из запроса):

Code Block
languagebash
openssl ca -engine gost -keyfile ca.key -cert ca.crt -in user.csr -out user.crt -outform PEM -batch

...

  • Получаем список подключенных к компьютеру устройств Рутокен ЭЦП
  • Получаем список всех имеющихся пользовательских сертификатов на выбранном Рутокен ЭЦП
  • Визуализируем каждый сертификат
  • Пользователь выбирает нужный сертификат
  • Сервер формирует начальную последовательность случайных данных (строку salt) и отправляет ее на клиент
  • Вызываем на клиенте authenticate. При передаче salt в функцию плагина authenticate данная последовательность дополняется дополнительными случайными данными размером в 32 символа, и происходит подпись итоговой последовательности на выбранном пользователем сертификате в формате CMS attached
  • Подпись отправляется на сервер
  • На сервере происходит проверка CMS attached подписи с использованием корневого сертификата
  • Из CMS attached сообщения извлекается итоговая случайная последовательность, “отсоединяется” salt и происходит сравнение
  • Если сравнение успешно, то регистрируем пользователя по сертификату, который содержится в CMS attached сообщении

...

Code Block
languagebash
titleПроверка подписи на сервере:
openssl cms -engine gost -verify -in sign.cms -inform PEM -CAfile ca.crt -out data.file -certsout user.cr

...

Code Block
languagebash
titleПоказать DN субъекта (subject):
openssl x509 -in cert.pem -noout -subject

...


 

Code Block
languagebash
titleПоказать DN издателя (issuer):
openssl x509 -in cert.pem -noout -issuer


 

 

Code Block
languagebash
titleПоказать почтовый адрес субъекта:
openssl x509 -in cert.pem -noout -email

...

  • сервер формирует начальную последовательность случайных данных (строку salt) и отправляет ее на клиент
  • при передаче salt в функцию плагина authenticate данная последовательность дополняется случайными данными размером в 32 символа, и происходит подпись итоговой последовательности на выбранном пользователем сертификате в формате CMS attached
  • подпись отправляется на сервер
  • на сервере происходит проверка подписи
  • из CMS attached сообщения извлекается итоговая случайная последовательность, “отсоединяется” salt и происходит сравнение
  • в случае успешной проверки пользователь аутентифицируется на основе сертификата, извлеченного из сообщения CMS

...

  • формируется текстовое сообщение (строка), формирование сообщения может происходить как на сервере, так и на клиенте
  • если требуется подписать документ произвольного формата (например, PDF), то требуется перекодировать его в формат base64
  • строка, содержащая данные для подписи, передается в функцию sign
  • если строка представляет собой закодированные в base64 данные, то параметр функции isBase64 должен быть установлен в true, при этом перед подписью произойдет декодирование данных из base64
  • если требуется использовать аппаратное вычисление хэш-функции ГОСТ Р 34.11-94 (сертифицированная реализация, скорость 60-70 Кб/c), то в options нужно установить опцию useHardwareHash в true. Если данная опция установлена в false, то будет использована быстрая программная реализация хэш-функции ГОСТ Р 34.11-942012
  • если требуется сформировать “отсоединенную” (detached) подпись CMS, то нужно установить опцию detached в true, иначе будет сформирована “присоединенная” (attached) подпись
  • для того, чтобы включить/не включить пользовательский сертификат в подписанное CMS-сообщение существует опция addUserCertificate
  • Установка опции addSignTime в true приведет к тому, что в подписанное CMS-сообщение будет добавлено системное время в качестве подписанного атрибута

...


Данные ссылки могут быть полезны разработчикам инфосистем с поддержкой ЭЦП на базе Рутокен Плагин и openssl:

Демосистема Рутокен Плагин
WEB-сервис генерации ключей, формирования запросов, управления сертификатами, формирования шаблонов запросов на сертификаты 
Документация по использованию утилиты openssl с российскими крипталгоритмами
Пример скрипта на PHP, использующего утилиту openssl