Page tree

Versions Compared

Key

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

...



Данные сценарии предполагают клиент-серверное взаимодействие, написание клиентских скриптов на JavaScript и соответствующих им серверных вызовов openssl.

Общие операции

 

Операции с устройством

...

Поиск подключенных устройств

...


Здесь первым параметром выступает старый PIN-код, а вторым новый PIN-код.

 

Работа с сертификатами


1. На токене могут храниться 3 категории сертификатов:

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



2. Для чтения сертификатов, хранящихся на устройстве, не требуется авторизация на устройство.

Code Block
languagejs
titleПример чтения пользовательских сертификатов с устройства:
 var certs = Array();

try
{   
    certs = plugin.enumerateCertificates(deviceId, plugin.CERT_CATEGORY_USER);
}
catch (error) 
{
    console.log(error);
}


3. Сертификат можно экспортировать в PEM-формате:

Code Block
languagejs
var certpem;

try
{   
    certpem = plugin.getCertificate(deviceId, certId);
}
catch (error) 
{
    console.log(error);
}

Получится примерно такая строка:

Code Block
-----BEGIN CERTIFICATE-----
MIIBmjCCAUegAwIBAgIBATAKBgYqhQMCAgMFADBUMQswCQYDVQQGEwJSVTEPMA0G
A1UEBxMGTW9zY293MSIwIAYDVQQKFBlPT08gIkdhcmFudC1QYXJrLVRlbGVjb20i
MRAwDgYDVQQDEwdUZXN0IENBMB4XDTE0MTIyMjE2NTEyNVoXDTE1MTIyMjE2NTEy
NVowEDEOMAwGA1UEAxMFZmZmZmYwYzAcBgYqhQMCAhMwEgYHKoUDAgIjAQYHKoUD
AgIeAQNDAARADKA/O1Zw50PzMpcNkWnW39mAJcTehAhkQ2Vg7bHkIwIdf7zPe2Px
HyAr6lH+stqdACK6sFYmkZ58cBjzL0WBwaNEMEIwJQYDVR0lBB4wHAYIKwYBBQUH
AwIGCCsGAQUFBwMEBgYpAQEBAQIwCwYDVR0PBAQDAgKkMAwGA1UdEwEB/wQCMAAw
CgYGKoUDAgIDBQADQQD5TY55KbwADGKJRK+bwCGZw24sdIyayIX5dn9hrKkNrZsW
detWY3KJFylSulykS/dfJ871IT+8dXPU5A7WqG4+
-----END CERTIFICATE-----

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 можно удалить сертификат с токена.

Работа с ключевыми парами ГОСТ Р 34.10-2001


1. Для получения декрипторов ключевых пар, хранящихся на устройстве, требуется ввод PIN-кода. Следует понимать, что само значение закрытого ключ получено быть не может, так как ключ является неизвлекаемым.

Code Block
languagejs
var keys = Array();

try
{   
    plugin.login(deviceId, "12345678");
    keys = plugin.enumerateKeys(deviceId, null);
}
catch (error) 
{
    console.log(error);
}


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


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

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

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

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


Openssl поддерживает российские криптоалгоритмы, начиная с версии 1.0. Для того, чтобы их использовать, в openssl требуется подгружать engine gost. В большинстве дистрибутивов openssl эта библиотека присутствует. Чтобы engine подгружалась, можно прописать ее в конфигурационном файле openssl:

[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 на выбранном Рутокен ЭЦП
  • Cоздаем запрос PKCS#10 на сертификат для сгенерированной ключевой пары
  • Отправляем запрос на сервер
  • На сервере создаем сертификат, привязываем к аккаунту (сам сертификат или его дескриптор). Следует отметить, что дескрипторы сертификатов, полученные при вызове функции enumerateCertificates, являются уникальными и неизменными
  • Отправляем сертификат на клиент
  • На клиенте визуализируем полученный сертификат
  • Импортируем полученный сертификат в Рутокен ЭЦП


Последовательность вызовов в клиентском скрипте будет следующей: