...
- пользовательские (константа в плагине CERT_CATEGORY_USER)
Это сертификаты, связанные с закрытым ключом пользователя. Применяются, например, для подписи CMS/PKCS#7, аутентификации пользователя в протоколе TLS.
Если сертификат импортируется как пользовательский, то при импорте будет произведен поиск в устройстве соответствующего ему закрытого ключа. Если такой ключ будет найден, то сертификат будет «привязан» к этому ключу. Если ключ найден не будет, то вернется ошибка. - корневые (константа в плагине CERT_CATEGORY_CA)
Это сертификаты издателей сертификатов, применяющиеся для проверки подписи под сертификатами. Подобная проверка подписи (построение цепочки доверия) позволяет определить, доверяет ли пользователь подписи другого пользователя. Например, в функции плагина verify есть режим проверки сертификата, на котором было подписано сообщение. При этом используется хранилище корневых сертификатов на токене, созданное импортом корневых сертификатов на токен. - другие (константа в плагине CERT_CATEGORY_OTHER)
Это сертификаты, которые не связаны с закрытым ключом и не являются корневыми.
...
4. Сертификат можно распарсить вызовом функции parseCertificate и получить из него DN Subject, DN Issuer, расширения, значение открытого ключа, подпись, серийный номер, срок действия и т.п.
5. Сертификат можно записать на устройство.
Code Block | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
Code Block | ||||
| ||||
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 | ||
---|---|---|
| ||
openssl genpkey -engine gost -algorithm GOST2001gost2012_256 -pkeyopt paramset:A -out ca.key |
...
Code Block | ||
---|---|---|
| ||
openssl req -engine gostutf8 -x509 -new -key caseckey.keypem -out ca.crt |
После ввода необходимой информации об издателе в файле ca.crt будет создан сертификат УЦ.
Полученный от клиента запрос сохраняем в файл user.csr и выдаем на его основе сертификат (без модификации данных из запроса):
Code Block | ||
---|---|---|
| ||
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 | ||||
---|---|---|---|---|
| ||||
openssl cms -engine gost -verify -in sign.cms -inform PEM -CAfile ca.crt -out data.file -certsout user.cr |
...
Code Block | ||||
---|---|---|---|---|
| ||||
openssl x509 -in cert.pem -noout -subject |
...
Code Block | ||||
---|---|---|---|---|
| ||||
openssl x509 -in cert.pem -noout -issuer |
Code Block | ||||
---|---|---|---|---|
| ||||
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