C_GenerateKey

CK_RV C_GenerateKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey)


Параметры:    

  • hSession (in) – дескриптор сеанса.
  • pMechanism (in) – указатель на механизм.
  • pTemplate (in) – указатель на шаблон объекта ключа.
  • ulCount (in) – количество атрибутов в шаблоне.
  • phKey (in/out) – идентификатор создаваемого ключа.

Генерирует секретный ключ.

Особенности приложений:

  • Приложение GOST.          

Рекомендуется использовать механизм аппаратной генерации ключевой информации на СКЗИ с защитой ключа.

 См. C_EncryptInit(), C_DecryptInit().

Приведенные ниже механизмы применяются только для сессионных ключей:

    • CKM_GOST28147_KEY_GEN (0x00001220) – механизм генерации ключей, соответствующий стандарту ГОСТ 28147–89.
    • CKM_MAGMA_KEY_GEN (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x034UL) - механизм генерации ключей по стандарту [ГОСТ 34.12-2018] для алгоритма Магма.
    • CKM_KUZNECHIK_KEY_GEN (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x030UL) - механизм генерации ключей по стандарту [ГОСТ 34.12-2018] для алгоритма Кузнечик.
  • Приложение PKI.

    Поддерживаемые механизмы:

    • CKM_DES2_KEY_GEN (0x00000130) – механизм генерации ключей DES двойной длины.
    • CKM_DES3_KEY_GEN (0x00000131) – механизм генерации ключей для алгоритма triple-DES.
    • CKM_TLS_PRE_MASTER_KEY_GEN (0x00000374) – механизм генерации 48-байтных секретных ключей, используемых при создании pre_master ключей для протокола TLS 1.0.
    • CKM_AES_KEY_GEN (0x00001080) – механизм генерации ключей для алгоритма AES.

Запускается в режимах:


Результат:    

  • CKR_ARGUMENTS_BAD – недопустимые аргументы.
  • CKR_ATTRIBUTE_READ_ONLY – невозможно установить значение атрибута, т.к. он поддерживает только чтение.
  • CKR_ATTRIBUTE_TYPE_INVALID – недопустимый тип атрибута.
  • CKR_ATTRIBUTE_VALUE_INVALID – недопустимое значение атрибута.
  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека еще не была инициализирована (см. C_Initialize()).
  • CKR_DEVICE_ERROR – возникла проблема с токеном и/или слотом.
  • CKR_DEVICE_MEMORY – памяти токена недостаточно для данной операции.
  • CKR_DEVICE_REMOVED – токен был изъят из слота.
  • CKR_FUNCTION_CANCELED – функция была отменена в момент исполнения.
  • CKR_FUNCTION_FAILED – выполнение функции было прервано или она не может быть выполнена.
  • CKR_GENERAL_ERROR – общий сбой при работе с библиотекой.
  • CKR_HOST_MEMORY – компьютер, на котором запущена библиотека, не имеет достаточно памяти для выполнения функции.
  • CKR_MECHANISM_INVALID – недопустимый механизм.
  • CKR_MECHANISM_PARAM_INVALID – недопустимый параметр механизма.
  • CKR_OK – функция выполнена успешно.
  • CKR_OPERATION_ACTIVE – на устройстве уже есть активная операция, что не позволяет активизировать данную операцию.
  • CKR_PIN_EXPIRED – срок действия указанного PIN-кода истек.
  • CKR_SESSION_CLOSED – сеанс был закрыт в момент выполнения функции.
  • CKR_SESSION_HANDLE_INVALID – недопустимый дескриптор сеанса.
  • CKR_SESSION_READ_ONLY – сеанс открыт только на чтение.
  • CKR_TEMPLATE_INCOMPLETE – шаблон, указанный для создания объекта, неполон.
  • CKR_TEMPLATE_INCONSISTENT – шаблон, указанный для создания объекта, содержит конфликтующие атрибуты.
  • CKR_TOKEN_WRITE_PROTECTED – данный токен защищен от записи.
  • CKR_USER_NOT_LOGGED_IN – действие не может быть выполнено, т.к. пользователь не залогинен.

Совет: Полный список ошибок см. в приложении.

Пример генерации сессионного ключа для GOST

Пример генерации ключа ГОСТ 28147:

<pre>static CK_BYTE id_Gost28147_89_CryptoPro_A_ParamSet[] = { 0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x1F, 0x01 };
 
// результат выполнения функции
CK_RV rv = CKR_OK;
 
// дескриптор сессии
CK_SESSION_HANDLE pkcs11SessionHandle;
 
// механизм генерации ключей
CK_MECHANISM pkcs11GenKeyMechanism = {CKM_GOST28147_KEY_GEN, NULL, 0};
 
// шаблон ключа
CK_ATTRIBUTE pkcs11SessionKeyTemplate[] =
{
{CKA_GOST28147_PARAMS, id_Gost28147_89_CryptoPro_A_ParamSet, sizeof(id_Gost28147_89_CryptoPro_A_ParamSet)}
};
 
// дескриптор сессионного ключа PKCS#11
CK_OBJECT_HANDLE pkcs11SessionKeyHandle;
 
// функция генерирует ключ, используя заданный шаблон
rv = C_GenerateKey(pkcs11SessionHandle,
&amp;pkcs11GenKeyMechanism,
pkcs11SessionKeyTemplate,
sizeof(pkcs11SessionKeyTemplate)/sizeof(CK_ATTRIBUTE),
&amp;pkcs11SessionKeyHandle);
if(rv != CKR_OK)
{
PrintError(&quot;C_GenerateKey&quot;, rv);
return;
}</pre>

Возможные значения атрибута CKA_GOST28147_PARAMS описаны в приложении.
Более полную информацию о работе с объектами смотри в приложении.

Пример генерации ключа Магма и Кузнечик:

<pre> CK_RV rv;
CK_OBJECT_HANDLE hKey = CK_INVALID_HANDLE; // дескриптор сгенерированного ключа
CK_SESSION_HANDLE session = ...; // считаем, что дескриптор сессии уже получен
 
// переменные для хранения значений атрибутов
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; // класс объекта - секретный ключ
CK_BBOOL token = CK_FALSE; // сессионный ключ
CK_BBOOL privateKey = CK_TRUE; // доступ к объекту ключа может быть только в аутентифицированной сессии
CK_BBOOL encrypt = CK_TRUE; // на ключе можно шифровать
CK_BBOOL decrypt = CK_TRUE; // на ключе можно расшифровывать
&nbsp; &nbsp; CK_BBOOL extractable = CK_TRUE; // Ключ может быть экспортирован
CK_BBOOL sensitive = CK_TRUE; // Ключ является чувствительным
CK_KEY_TYPE keyType = CKK_MAGMA; // CKK_KUZNECHIK
 
// атрибуты ключа
CK_ATTRIBUTE keyTemplate[] = {
{ CKA_CLASS, &amp;keyClass, sizeof(keyClass) },
{ CKA_KEY_TYPE, &amp;keyType, sizeof(keyType) },
{ CKA_TOKEN, &amp;token, sizeof(token) },
{ CKA_PRIVATE, &amp;privateKey, sizeof(privateKey) },
{ CKA_ENCRYPT, &amp;encrypt, sizeof(encrypt) },
{ CKA_DECRYPT, &amp;decrypt, sizeof(decrypt) },
{ CKA_EXTRACTABLE, &amp;extractable, sizeof(extractable) },
{ CKA_SENSITIVE, &amp;sensitive, sizeof(sensitive) }
};
 
// Механизм генерации ключа
CK_MECHANISM mechanism;
mechanism.mechanism = CKM_MAGMA_KEY_GEN; // CKM_KUZNECHIK_KEY_GEN
&nbsp; &nbsp; mechanism.pParameter = NULL_PTR;
mechanism.ulParameterLen = 0;
 
// Генерация ключа
rv = C_GenerateKey(session, &amp;mechanism, keyTemplate, sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE), &amp;hKey);
if (rv != CKR_OK)
{
PrintError(&quot;C_GenerateKey&quot;, rv);
}</pre>

C_GenerateKeyPair

CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSessionCK_MECHANISM_PTR pMechanismCK_ATTRIBUTE_PTR pPublicKeyTemplateCK_ULONG ulPublicKeyAttributeCount

CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey)


Параметры:    

  • hSession (in) – дескриптор сеанса.
  • pMechanism (in) – указатель на механизм.
  • pPublicKeyTemplate (in) – шаблон открытого ключа.
  • ulPublicKeyAttributeCount (in) – количество атрибутов в шаблоне открытого ключа.
  • pPrivateKeyTemplate (in) – шаблон закрытого ключа.
  • ulPrivateKeyAttributeCount (in) – количество атрибутов в шаблоне закрытого ключа.
  • phPublicKey (in/out) – указатель, получающий дескриптор созданного открытого ключа.
  • phPrivateKey (in/out) – указатель, получающий дескриптор созданного закрытого ключа.

Генерирует ключевую пару и возвращает идентификаторы закрытого и открытого ключей.

Поддерживаются следующие механизмы:

  • Приложение GOST версии 2.5.5, 2.5.9

    • CKM_GOSTR3410_KEY_PAIR_GEN (0x00001200) – механизм генерации ключевой пары в соответствии со стандартом ГОСТ Р 34.10–2001.
    • CKM_GOSTR3410_256_KEY_PAIR_GEN (идентичен CKM_GOSTR3410_KEY_PAIR_GEN) – механизм генерации ключевой пары в соответствии со стандартом ГОСТ Р 34.10–2012 (длина ключа 256 бит).
  • Приложение GOST версии 2.5.13

    • CKM_GOSTR3410_KEY_PAIR_GEN (0x00001200) – механизм генерации ключевой пары в соответствии со стандартом ГОСТ Р 34.10–2001.
    • CKM_GOSTR3410_256_KEY_PAIR_GEN (идентичен CKM_GOSTR3410_KEY_PAIR_GEN) – механизм генерации ключевой пары в соответствии со стандартом ГОСТ Р 34.10–2012 (длина ключа 256 бит).
    • CKM_GOSTR3410_512_KEY_PAIR_GEN (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x005) - механизм генерации ключевой пары в соответствии со стандартом ГОСТ 34.10-2018
  • Для генерации ключевых пар конкретного стандарта, помимо указания механизма, необходимо передавать соответствующее значение в атрибут CKA_GOSTR3411_PARAMS шаблона открытого ключа.




    ГОСТ Р 34.10–2001

    CKM_GOSTR3410_KEY_PAIR_GEN

    id-GostR3411-94-CryptoProParamSet

    ГОСТ Р 34.10–2012 (длина ключа 256 бит)

    CKM_GOSTR3410_256_KEY_PAIR_GEN

    id-tc26-gost3411-12-256

    ГОСТ Р 34.10–2018 (длина ключа 512 бит)

    CKM_GOSTR3410_512_KEY_PAIR_GEN

    id-tc26-gost3411-12-512

Совет: Значения атрибута CKA_GOSTR3411_PARAMS см. в приложении.

  • Приложение PKI

    • CKM_RSA_PKCS_KEY_PAIR_GEN (0x00000000) – механизм генерации ключевой пары для алгоритма RSA.
    • CKM_ECDSA_KEY_PAIR_GEN (0x00001040) – механизм генерации ключевой пары для алгоритма ECDSA.
    • CKM_EC_KEY_PAIR_GEN (0x00001040) – механизм генерации ключевой пары для алгоритма EC.

Запускается в режимах:


Результат:    

  • CKR_ARGUMENTS_BAD – недопустимые аргументы.
  • CKR_ATTRIBUTE_READ_ONLY – невозможно установить значение атрибута, т.к. он поддерживает только чтение.
  • CKR_ATTRIBUTE_TYPE_INVALID – недопустимый тип атрибута.
  • CKR_ATTRIBUTE_VALUE_INVALID – недопустимое значение атрибута.
  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека еще не была инициализирована (см. C_Initialize()).
  • CKR_DEVICE_ERROR – возникла проблема с токеном и/или слотом.
  • CKR_DEVICE_MEMORY – памяти токена недостаточно для данной операции.
  • CKR_DEVICE_REMOVED – токен был изъят из слота.
  • CKR_DOMAIN_PARAMS_INVALID – недопустимые или неподдерживаемые параметры домена.
  • CKR_FUNCTION_CANCELED – функция была отменена в момент исполнения.
  • CKR_FUNCTION_FAILED – выполнение функции было прервано или она не может быть выполнена.
  • CKR_GENERAL_ERROR – общий сбой при работе с библиотекой.
  • CKR_HOST_MEMORY – компьютер, на котором запущена библиотека, не имеет достаточно памяти для выполнения функции.
  • CKR_MECHANISM_INVALID – недопустимый механизм.
  • CKR_MECHANISM_PARAM_INVALID – недопустимый параметр механизма.
  • CKR_OK – функция выполнена успешно.
  • CKR_OPERATION_ACTIVE – на устройстве уже есть активная операция, что не позволяет активизировать данную операцию.
  • CKR_PIN_EXPIRED – срок действия указанного PIN-кода истек.
  • CKR_SESSION_CLOSED – сеанс был закрыт в момент выполнения функции.
  • CKR_SESSION_HANDLE_INVALID – недопустимый дескриптор сеанса.
  • CKR_SESSION_READ_ONLY – сеанс открыт только на чтение.
  • CKR_TEMPLATE_INCOMPLETE – шаблон, указанный для создания объекта, неполон.
  • CKR_TEMPLATE_INCONSISTENT – шаблон, указанный для создания объекта, содержит конфликтующие атрибуты.
  • CKR_TOKEN_WRITE_PROTECTED – данный токен защищен от записи.
  • CKR_USER_NOT_LOGGED_IN – действие не может быть выполнено, т.к. пользователь не залогинен.

Совет: Полный список ошибок см. в приложении.

Примеры генерации ключевой пары для GOST

Пример генерации ключевой пары ГОСТ Р 34.10–2012 (длина ключа 256 бит) на языке C:

<pre>static CK_BYTE id_GostR3410_2001_CryptoPro_A_ParamSet[] = { 0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 };
static CK_BYTE id_tc26_gost3411_12_256[] = { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x02 };
 
CK_BBOOL bTrue = CK_TRUE;
CK_BBOOL bFalse = CK_FALSE;
 
// результат выполнения функции
CK_RV rv = CKR_OK;
 
// дескриптор сессии
CK_SESSION_HANDLE session;
 
// механизм генерации ключевой пары
CK_MECHANISM mechanism = {CKM_GOSTR3410_256_KEY_PAIR_GEN, NULL, 0};
 
// параметры шаблона закрытого ключа
CK_OBJECT_CLASS privKeyClass = CKO_PRIVATE_KEY;
CK_UTF8CHAR privKeyLabel[] = &quot;Private Key GOST R 34.10-2001 256&quot;;
CK_KEY_TYPE privKeyType = CKK_GOSTR3410;
 
// шаблон закрытого ключа
CK_ATTRIBUTE privKeyTemplate[] =
{
{CKA_CLASS, &amp;privKeyClass, sizeof(privKeyClass)}, // класс
{CKA_KEY_TYPE, &amp;privKeyType, sizeof(privKeyType)}, // тип ключа
{CKA_TOKEN, (CK_VOID_PTR) &amp;bTrue, sizeof(bTrue)}, // объект хранится в токене
{CKA_LABEL, (CK_VOID_PTR) privKeyLabel, (CK_ULONG) strlen(privKeyLabel)}, // метка закрытого ключа
{CKA_PRIVATE, &amp;bTrue, sizeof(bTrue) }, // не виден без ввода PIN-кода пользователя
};
 
// параметры шаблона открытого ключа
CK_OBJECT_CLASS pubKeyClass = CKO_PUBLIC_KEY;
CK_UTF8CHAR pubKeyLabel[] = &quot;Public Key GOST R 34.10-2001 256&quot;;
CK_KEY_TYPE pubKeyType = CKK_GOSTR3410;
 
// шаблон открытого ключа
CK_ATTRIBUTE pubKeyTemplate[] =
{
{CKA_CLASS, &amp;privKeyClass, sizeof(privKeyClass)}, // класс
{CKA_KEY_TYPE, &amp;privKeyType, sizeof(privKeyType)}, // тип ключа
{CKA_TOKEN, (CK_VOID_PTR) &amp;bTrue, sizeof(bTrue)}, // объект хранится в токене
{CKA_LABEL, (CK_VOID_PTR) pubKeyLabel, (CK_ULONG) strlen(pubKeyLabel)}, // метка закрытого ключа
{CKA_PRIVATE, &amp;bFalse, sizeof(bFalse) }, // виден без ввода PIN-кода пользователя
 
{
CKA_GOSTR3410_PARAMS,
(CK_VOID_PTR) id_GostR3410_2001_CryptoPro_A_ParamSet,
sizeof(id_GostR3410_2001_CryptoPro_A_ParamSet)
}, // тип ключевой пары
 
{
CKA_GOSTR3411_PARAMS,
(CK_VOID_PTR) id_tc26_gost3411_12_256,
sizeof(id_tc26_gost3411_12_256)
} // стандарт алгоритма хэширования
};
 
// дескрипторы открытого и закрытого ключа ключевой пары PKCS#11
CK_OBJECT_HANDLE pubKeyHandle, privKeyHandle;
 
// функция генерирует ключевую пару
rv = C_GenerateKeyPair(session,
&amp;mechanism,
pubKeyTemplate, sizeof(pubKeyTemplate)/sizeof(CK_ATTRIBUTE),
privKeyTemplate, sizeof(privKeyTemplate)/sizeof(CK_ATTRIBUTE),
&amp;pubKeyHandle,
&amp;privKeyHandle);
if(rv != CKR_OK)
{
PrintError(&quot;C_GenerateKeyPair&quot;, rv);
return;
}</pre><p><br /></p>

Пример генерации ключевой пары ГОСТ Р 34.10–2018 на языке C:

<pre> CK_BYTE oid_tc26_gost_3410_12_512_paramSetA[] = { 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x02, 0x01 };
CK_BYTE oid_tc26_gost3411_12_512[] = { 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x02, 0x03 };
 
CK_RV rv = CKR_OK;
CK_MECHANISM asymKeyMechanism512 = {CKM_GOSTR3410_512_KEY_PAIR_GEN, 0, 0};
CK_OBJECT_HANDLE publicKey512 = CK_INVALID_HANDLE;
CK_OBJECT_HANDLE privateKey512 = CK_INVALID_HANDLE;
CK_BBOOL bTrue = CK_TRUE;
CK_BBOOL bFalse = CK_FALSE;
CK_KEY_TYPE keyType2012 = CKK_GOSTR3410_512;
CK_OBJECT_CLASS pubkeyClass = CKO_PUBLIC_KEY;
CK_OBJECT_CLASS privkeyClass = CKO_PRIVATE_KEY;
 
CK_ATTRIBUTE PublicKey512Template[] = {
{CKA_CLASS, &amp;pubkeyClass, sizeof(pubkeyClass) }, // Класс - открытый ключ
{CKA_KEY_TYPE, &amp;keyType2012, sizeof(keyType2012) }, // Тип ключа - ГОСТ Р 34.10-2012(512)
{CKA_TOKEN, &amp;bTrue, sizeof(bTrue) }, // Ключ является объектом токена
{CKA_PRIVATE, &amp;bFalse, sizeof(bFalse) }, // Ключ доступен без аутентификации на токене
{CKA_VERIFY, &amp;bTrue, sizeof(bTrue) }, // Ключ предназначен для проверки подписи
{CKA_GOSTR3410_PARAMS, (CK_VOID_PTR)oid_tc26_gost_3410_12_512_paramSetA, sizeof(oid_tc26_gost_3410_12_512_paramSetA) }, // Параметры алгоритма ГОСТ Р 34.10-2012(512)
{CKA_GOSTR3411_PARAMS, oid_tc26_gost3411_12_512, sizeof(oid_tc26_gost3411_12_512)}, // Параметры алгоритма ГОСТ Р 34.11-2012(512)
};
 
CK_ATTRIBUTE PrivateKey512Template[] = {
{CKA_CLASS, &amp;privkeyClass, sizeof(privkeyClass) }, // Класс - закрытый ключ
{CKA_KEY_TYPE, &amp;keyType2012, sizeof(keyType2012) }, // Тип ключа - ГОСТ Р 34.10-2012(512)
{CKA_TOKEN, &amp;bTrue, sizeof(bTrue) }, // Ключ является объектом токена
{CKA_PRIVATE, &amp;bTrue, sizeof(bTrue) }, // Ключ доступен только после аутентификации на токене
{CKA_SIGN, &amp;bTrue, sizeof(bTrue) }, // Ключ предназначен для подписи
{CKA_GOSTR3410_PARAMS, (CK_VOID_PTR)oid_tc26_gost_3410_12_512_paramSetA, sizeof(oid_tc26_gost_3410_12_512_paramSetA) }, // Параметры алгоритма ГОСТ Р 34.10-2012(512)
{CKA_GOSTR3411_PARAMS, oid_tc26_gost3411_12_512, sizeof(oid_tc26_gost3411_12_512)}, // Параметры алгоритма ГОСТ Р 34.11-2012(512)
};
 
CK_ATTRIBUTE keyAttribute = {CKA_VALUE, NULL, 0};
 
rv = Functions()-&gt;C_GenerateKeyPair(SessionHandle(), &amp;asymKeyMechanism512,
PublicKey512Template, sizeof(PublicKey512Template) / sizeof(CK_ATTRIBUTE),
PrivateKey512Template, sizeof(PrivateKey512Template) / sizeof(CK_ATTRIBUTE),
&amp;publicKey512, &amp;privateKey512);</pre><p><br /></p>

C_WrapKey

CK_RV C_WrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hWrappingKey, CK_OBJECT_HANDLE hKey, CK_BYTE_PTR pWrappedKey, 

CK_ULONG_PTR pulWrappedKeyLen)


Параметры:    

  • hSession (in) – дескриптор сеанса.
  • pMechanism (in) – указатель на механизм.
  • hWrappingKey (in) – указатель на ключ экспорта.
  • hKey (in) – указатель на исходный ключ.
  • pWrappedKey (in/out) – указатель на массив для экспортированного ключа.
  • pulWrappedKeyLen (in/out) – указатель на размер массива экспортированного ключа.

Производит экспорт симметричного сессионного ключа на симметричном ключе согласования.

Особенности механизма приложения GOST

Используется аппаратный и программный экспорт ключа.

Аппаратный экспорт ключа (рекомендуемый режим)

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

  • Вводится понятие «виртуального секретного ключа», под которым понимается ключ, который может присутствовать (но не обязательно) в оперативной памяти изделия.

    Вызову функции должно предшествовать получение дескриптора «виртуального секретного ключа», который потом передается в качестве параметра функции. Поиск объекта виртуального ключа осуществляется по шаблону, содержащему атрибуты CKA_CLASS = CKO_SECRET_KEY, CKA_ID = ”VSKO_ID”.

    После экспорта ключа атрибут CKA_KT2_KEY_ACTIVE принимает значение CK_TRUE.

  • Также возможно экспортировать сгенерированный ранее секретный ключ. После завершения операции преобразования ключ удаляется из памяти изделия.

Программный экспорт ключа

      • При программном экспорте функция работает согласно стандарту. Доступные атрибуты:
        • CKA_KT2_KEY_WRAP (CKA_VENDOR_DEFINED | 0x0024) – если атрибут имеет значение CK_TRUE, используется алгоритм шифрования ключа содержимого по RFC 4357 п.6.1/6.2; в противном случае используется RFC 4357 п.6.3/6.4.
        • CKA_KT2_AUTOGENERATE_KEY (CKA_VENDOR_DEFINED | 0x0026) – если атрибут имеет значение CK_TRUE, будет сгенерирован случайный секретный ключ. По умолчанию принимается значение CK_TRUE.

Поддерживаются следующие механизмы:

  • Приложение GOST версии 2.5.5

    • CKM_GOST28147_KEY_WRAP (0x00001224) – механизм для импорта и экспорта ключей, соответствующий стандарту ГОСТ 28147–89.

    • CKM_GOSTR3410_KEY_WRAP (0x00001203) – механизм для импорта и экспорта ключей, соответствующий стандарту ГОСТ Р 34.10–2001.

  • Приложение GOST версии 2.5.13

    •   CKM_KUZNECHIK_KEXP_15_WRAP (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x02BUL) – механизм экспорта и импорта ключей, построенный на основе алгоритма Кузнечик
    •   CKM_MAGMA_KEXP_15_WRAP (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x02CUL) – механизм экспорта и импорта ключей, построенный на основе алгоритма Магма
    •   CKM_GOST28147_KEY_WRAP  (0x00001224) – механизм для импорта и экспорта ключей, соответствующий стандарту ГОСТ 28147–89.
    •     CKM_GOSTR3410_KEY_WRAP  (0x00001203) – механизм для импорта и экспорта ключей, соответствующий стандарту ГОСТ Р 34.10–2001.
  • Приложение PKI

    • CKM_RSA_PKCS (0x00000001) – механизм для импорта и экспорта ключей с использованием ключевой пары и алгоритма RSA.
    • CKM_DES3_ECB (0x00000132) – механизм для импорта и экспорта ключей в режиме ECB с использованием алгоритма triple-DES.
    • CKM_DES3_CBC (0x00000133) – механизм для импорта и экспорта ключей в режиме CBC с использованием алгоритма triple-DES.
    • CKM_AES_ECB (0x00001081) – механизм для импорта и экспорта ключей в режиме ECB с использованием алгоритма AES.
    • CKM_AES_CBC (0x00001082) – механизм для импорта и экспорта ключей в режиме CBC с использованием алгоритма AES.

Запускается в режимах:


Результат:    

  • CKR_ARGUMENTS_BAD – недопустимые аргументы.
  • CKR_BUFFER_TOO_SMALL – вывод функции слишком велик для предоставленного буфера.
  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека еще не была инициализирована (см. C_Initialize()).
  • CKR_DEVICE_ERROR – возникла проблема с токеном и/или слотом.
  • CKR_DEVICE_MEMORY – памяти токена недостаточно для данной операции.
  • CKR_DEVICE_REMOVED – токен был изъят из слота.
  • CKR_FUNCTION_CANCELED – функция была отменена в момент исполнения.
  • CKR_FUNCTION_FAILED – выполнение функции было прервано или она не может быть выполнена.
  • CKR_GENERAL_ERROR – общий сбой при работе с библиотекой.
  • CKR_HOST_MEMORY – компьютер, на котором запущена библиотека, не имеет достаточно памяти для выполнения функции.
  • CKR_KEY_HANDLE_INVALID – недопустимый дескриптор ключа.
  • CKR_KEY_NOT_WRAPPABLE – библиотека не может экспортировать данный ключ.
  • CKR_KEY_SIZE_RANGE – размер ключа лежит за пределами, поддерживаемыми библиотекой.
  • CKR_KEY_UNEXTRACTABLE – библиотека не может экспортировать данный ключ, так как атрибут CKA_EXTRACTABLE установлен в значение CK_FALSE.
  • CKR_MECHANISM_INVALID – недопустимый механизм.
  • CKR_MECHANISM_PARAM_INVALID – недопустимый параметр механизма.
  • CKR_OK – функция выполнена успешно.
  • CKR_OPERATION_ACTIVE – на устройстве уже есть активная операция, что не позволяет активизировать данную операцию.
  • CKR_PIN_EXPIRED – срок действия указанного PIN-кода истек.
  • CKR_SESSION_CLOSED – сеанс был закрыт в момент выполнения функции.
  • CKR_SESSION_HANDLE_INVALID – недопустимый дескриптор сеанса.
  • CKR_USER_NOT_LOGGED_IN – действие не может быть выполнено, т.к. пользователь не залогинен.
  • CKR_WRAPPING_KEY_HANDLE_INVALID – недопустимый указатель на ключ экспорта

Примечание: Данный аргумент возвращается только функцией C_WrapKey.

  • CKR_WRAPPING_KEY_SIZE_RANGE – размер ключа экспорта лежит за пределами, поддерживаемыми библиотекой.

Примечание: Данный аргумент возвращается только функцией C_WrapKey.

  • CKR_WRAPPING_KEY_TYPE_INCONSISTENT – данный ключ экспорта невозможно использовать с указанным механизмом.

Примечание: Данный аргумент возвращается только функцией C_WrapKey.

Совет: Полный список ошибок см. в приложении.

Примеры экспорта ключа для GOST

Пример экспорта ключа с использованием CKM_GOSTR3410_KEY_WRAP и виртуального секретного ключа на языке C++:

<pre>// получаем дескриптор сессии
CK_SESSION_HANDLE hSession = &hellip; ;
 
// режим Пользователя
CK_UTF8CHAR pin[] = &quot;1234567890&quot;;
C_Login(hSession, CKU_USER, pin, strlen(pin));
 
 
// получаем дескрипторы приватного ключа Отправителя и публичного ключа Получателя
CK_OBJECT_HANDLE hReceiverPublicKey = &hellip; ;
CK_OBJECT_HANDLE hSenderPrivateKey = &hellip; ;
 
CK_OBJECT_CLASS ckaClass = CKO_SECRET_KEY;
CK_BYTE ckaId[] = &quot;VSKO_ID&quot;; // &quot;VSKO_ID&quot;
 
// атрибуты поиска виртуального ключа
CK_ATTRIBUTE searchAtt[] = {
{CKA_CLASS, &amp;ckaClass, sizeof(ckaClass)},
{CKA_ID, ckaId, sizeof(ckaId) - 1}
};
 
CK_OBJECT_HANDLE hVirtualSecretKey = CK_INVALID_HANDLE; // дескриптор виртуального секретного ключа
CK_ULONG ulObjectsCount = 5;
 
// поиск виртуального ключа
C_FindObjectsInit(hSession, searchAtt, 2);
C_FindObjects(hSession, &amp;hVirtualSecretKey, 1, &amp;ulObjectsCount);
C_FindObjectsFinal(hSession);
 
// параметры экспорта ключа
CK_GOSTR3410_KEY_WRAP_PARAMS wrapParams;
memset(&amp;wrapParams, 0, sizeof(wrapParams));
 
wrapParams.hKey = hSenderPrivateKey;
 
CK_MECHANISM ckWrapMechanism;
ckWrapMechanism.mechanism = CKM_GOSTR3410_KEY_WRAP;
ckWrapMechanism.pParameter = &amp;wrapParams;
ckWrapMechanism.ulParameterLen = sizeof(wrapParams);
 
// получаем требуемый размер для экспортированного представления
CK_ULONG wrappedKeySize = 0;
C_WrapKey(hSession, &amp;ckWrapMechanism, hReceiverPublicKey, hVirtualSecretKey, NULL, &amp;wrappedKeySize);
 
// генерируем и экспортируем ключ hVirtualSecretKey
std::vector&lt;CK_BYTE&gt; wrappedKey(wrappedKeySize);
C_WrapKey(hSession, &amp;ckWrapMechanism, hReceiverPublicKey, hVirtualSecretKey, &amp;wrappedKey[0], &amp;wrappedKeySize);</pre><p><br /></p>

Пример экспорта виртуального секретного ключа по CKM_MAGMA_KEXP_15_WRAP на языке C++:

<pre>CK_OBJECT_CLASS objectClass = CKO_SECRET_KEY;
CK_BYTE ckaId[] = &quot;VSKO_ID&quot;;
 
// шаблон поиска виртуального ключа
CK_ATTRIBUTE searchAtt[] = {
{CKA_CLASS, &amp;objectClass, sizeof(objectClass)},
{CKA_ID, ckaId, sizeof(ckaId) - 1}
};
CK_OBJECT_HANDLE hVirtualSecretKey = CK_INVALID_HANDLE; // дескриптор виртуального секретного ключа
CK_ULONG ulObjectsCount = 1;
// поиск виртуального ключа
C_FindObjectsInit(hSession, searchAtt, 2);
C_FindObjects(hSession, &amp;hVirtualSecretKey, 1, &amp;ulObjectsCount);
C_FindObjectsFinal(hSession);
 
// получаем дескрипторы приватного ключа Отправителя и публичного ключа Получателя
CK_OBJECT_HANDLE hReceiverPublicKey = &hellip; ;
CK_OBJECT_HANDLE hSenderPrivateKey = &hellip; ;
 
// механизм экспорта ключа
CK_MECHANISM ckWrapMech;
ckWrapMech.mechanism = CKM_MAGMA_KEXP_15_WRAP;
ckWrapMech.pParameter = (CK_VOID_PTR)(&amp;hSenderPrivate);
ckWrapMech.ulParameterLen = sizeof(CK_OBJECT_HANDLE);
 
// размер экспортного представления ключа
CK_ULONG wrappedKeySize;
 
// определяем длину экспортного представления
C_WrapKey(hSession, &amp;ckWrapMech, hReceiverPublic, hVirtualSecretKey, NULL_PTR, &amp;wrappedKeySize);
 
// выделяем память для экспортного представления ключа
std::vector&lt;CK_BYTE&gt; wrappedKey(wrappedKeySize);
 
// производим экспорт ключа
C_WrapKey(hSession, &amp;ckWrapMech, hReceiverPublic, hVirtualSecretKey, wrappedKey.data(), &amp;wrappedKeySize);</pre><p><br /></p>

Пример экспорта виртуального секретного ключа по CKM_KUZNECHIK_KEXP_15_WRAP на языке C++:

<pre>CK_OBJECT_CLASS objectClass = CKO_SECRET_KEY;
CK_BYTE ckaId[] = &quot;VSKO_ID&quot;;
 
// шаблон поиска виртуального ключа
CK_ATTRIBUTE searchAtt[] = {
{CKA_CLASS, &amp;objectClass, sizeof(objectClass)},
{CKA_ID, ckaId, sizeof(ckaId) - 1}
};
CK_OBJECT_HANDLE hVirtualSecretKey = CK_INVALID_HANDLE; // дескриптор виртуального секретного ключа
CK_ULONG ulObjectsCount = 1;
// поиск виртуального ключа
C_FindObjectsInit(hSession, searchAtt, 2);
C_FindObjects(hSession, &amp;hVirtualSecretKey, 1, &amp;ulObjectsCount);
C_FindObjectsFinal(hSession);
 
// получаем дескрипторы приватного ключа Отправителя и публичного ключа Получателя
CK_OBJECT_HANDLE hReceiverPublicKey = &hellip; ;
CK_OBJECT_HANDLE hSenderPrivateKey = &hellip; ;
 
// механизм экспорта ключа
CK_MECHANISM ckWrapMech;
ckWrapMech.mechanism = CKM_KUZNECHIK_KEXP_15_WRAP;
ckWrapMech.pParameter = (CK_VOID_PTR)(&amp;hSenderPrivate);
ckWrapMech.ulParameterLen = sizeof(CK_OBJECT_HANDLE);
 
// размер экспортного представления ключа
CK_ULONG wrappedKeySize;
 
// определяем длину экспортного представления
C_WrapKey(hSession, &amp;ckWrapMech, hReceiverPublic, hVirtualSecretKey, NULL_PTR, &amp;wrappedKeySize);
 
// выделяем память для экспортного представления ключа
std::vector&lt;CK_BYTE&gt; wrappedKey(wrappedKeySize);
 
// производим экспорт ключа
C_WrapKey(hSession, &amp;ckWrapMech, hReceiverPublic, hVirtualSecretKey, wrappedKey.data(), &amp;wrappedKeySize);</pre><p><br /></p>

Пример экспорта сессионного ключа для CKM_MAGMA_KEXP_15_WRAP на языке С++ (только для версии 2.5.13):

<pre>CK_RV rv = CKR_OK;
 
CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; // дескриптор сессии
CK_OBJECT_HANDLE kekKeyHandle = CK_INVALID_HANDLE; // дескриптор ключа, на котором производится импорт (CKK_MAGMA_TWIN_KEY)
CK_OBJECT_HANDLE cekKeyHandle = CK_INVALID_HANDLE; // дескриптор импортируемого ключа
 
// ...
// получаем дескриптор сессии
// далее предполагаем, в что ключи уже получены в рамках сессии
 
CK_BYTE iv[] = { 0x67, 0xBE, 0xD6, 0x54,}; // синхропосылка 4 байта (вектор инициализации)
 
// механизм экспорта ключа
CK_MECHANISM kexpMechanism = { CKM_MAGMA_KEXP_15_WRAP, iv, sizeof(iv) };
 
// длина экспортного представления ключа
CK_ULONG valueLength = 0;
 
// определяем длину экспортного представления
rv = C_WrapKey(hSession, &amp;kexpMechanism, kekKeyHandle, cekKeyHandle, NULL, &amp;valueLength);
 
// выделяем память для экспортного представления
std::vector&lt;CK_BYTE&gt; value(valueLength);
 
// производим экспорт ключа
rv = C_WrapKey(hSession, &amp;kexpMechanism, kekKeyHandle, cekKeyHandle, value.data(), &amp;valueLength);</pre><p><br /></p>

Пример экспорта сессионного ключа для CKM_KUZNECHIK_KEXP_15_WRAP на языке С++ (только для версии 2.5.13):

<pre>CK_RV rv = CKR_OK;
 
CK_SESSION_HANDLE hSession = CK_INVALID_HANDLE; // дескриптор сессии
CK_OBJECT_HANDLE kekKeyHandle = CK_INVALID_HANDLE; // дескриптор ключа, на котором производится импорт (CKK_KUZNECHIK_TWIN_KEY)
CK_OBJECT_HANDLE cekKeyHandle = CK_INVALID_HANDLE; // дескриптор импортируемого ключа
 
// ...
// получаем дескриптор сессии
// далее предполагаем, в что ключи уже получены в рамках сессии
CK_BYTE iv[] = { 0x09, 0x09, 0x47, 0x2D, 0xD9, 0xF2, 0x6B, 0xE8 }; // синхропосылка 8 байт (вектор инициализации)
 
// механизм экспорта ключа
CK_MECHANISM kexpMechanism = { CKM_KUZNECHIK_KEXP_15_WRAP, iv, sizeof(iv) };
 
// длина экспортного представления
CK_ULONG valueLength = 0;
 
// определяем длину экспортного представления
rv = C_WrapKey(hSession, &amp;kexpMechanism, kekKeyHandle, cekKeyHandle, NULL, &amp;valueLength);
 
// выделяем память для экспортного представления
std::vector&lt;CK_BYTE&gt; value(valueLength);
 
// производим экспорт ключа
rv = C_WrapKey(hSession, &amp;kexpMechanism, kekKeyHandle, cekKeyHandle, value.data(), &amp;valueLength);</pre><p><br /></p>

C_UnwrapKey

CK_RV C_UnwrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hUnwrappingKey, CK_BYTE_PTR pWrappedKey, CK_ULONG ulWrappedKeyLen, 

CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, CK_OBJECT_HANDLE_PTR phKey)


Параметры:    

  • hSession (in) – дескриптор сеанса.
  • pMechanism (in) – указатель на механизм.
  • hUnwrappingKey (in) – указатель на ключ импорта.
  • pWrappedKey (in) – указатель на массив, содержащий исходный зашифрованный ключ.
  • ulWrappedKeyLen (in) – размер массива для исходного ключа.
  • pTemplate (in) – указатель на шаблон сессионного ключа.
  • ulCount (in) – количество атрибутов в шаблоне.
  • phKey (out) – указатель на идентификатор импортированного сессионного ключа.

Производит импорт сессионного ключа на ключе согласования.

Особенности механизма приложения GOST

Используется аппаратный и программный импорт ключа.

Аппаратный импорт ключа

  • Вводится понятие «виртуального секретного ключа», под которым понимается ключ, который может присутствовать (но не обязательно) в оперативной памяти изделия. Вызову функции должно предшествовать получение дескриптора «виртуального секретного ключа», который потом передается в качестве параметра функции. Поиск объекта виртуального ключа осуществляется по шаблону, содержащему атрибуты CKA_CLASS = CKO_SECRET_KEY, CKA_ID = ”VSKO_ID”.
  • После импорта ключа атрибут CKA_KT2_KEY_ACTIVE принимает значение CK_TRUE.
  • После завершения операции преобразования ключ удаляется из памяти изделия, а атрибут CKA_KT2_KEY_ACTIVE принимает значение CK_FALSE.

Программный импорт ключа

      • При программном импорте функция работает согласно стандарту. Доступные атрибуты:
        • CKA_KT2_KEY_WRAP (CKA_VENDOR_DEFINED | 0x0024) – если атрибут имеет значение CK_TRUE, используется алгоритм шифрования ключа содержимого по RFC 4357 п.6.1/6.2; в противном случае используется RFC 4357 п.6.3/6.4.
        • CKA_KT2_AUTOGENERATE_KEY (CKA_VENDOR_DEFINED | 0x0026) – если атрибут имеет значение CK_TRUE, будет сгенерирован случайный секретный ключ. По умолчанию принимается значение CK_TRUE.

Поддерживаются следующие механизмы:

  • Приложение GOST версии 2.5.5

    • CKM_GOST28147_KEY_WRAP (0x00001224) – механизм для импорта и экспорта ключей, соответствующий стандарту ГОСТ 28147–89.

    • CKM_GOSTR3410_KEY_WRAP (0x00001203) – механизм для импорта и экспорта ключей, соответствующий стандарту ГОСТ Р 34.10–2001.

  • Приложение GOST версии 2.5.13

    •   CKM_KUZNECHIK_KEXP_15_WRAP (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x02BUL) – механизм экспорта и импорта ключей, построенный на основе алгоритма Кузнечик
    •   CKM_MAGMA_KEXP_15_WRAP (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x02CUL) – механизм экспорта и импорта ключей, построенный на основе алгоритма Магма
    •   CKM_GOST28147_KEY_WRAP  (0x00001224) – механизм для импорта и экспорта ключей, соответствующий стандарту ГОСТ 28147–89.
    •     CKM_GOSTR3410_KEY_WRAP  (0x00001203) – механизм для импорта и экспорта ключей, соответствующий стандарту ГОСТ Р 34.10–2001
  • Приложение PKI

    • CKM_RSA_PKCS (0x00000001) – механизм для импорта и экспорта ключей с использованием ключевой пары и алгоритма RSA.
    • CKM_DES3_ECB (0x00000132) – механизм для импорта и экспорта ключей в режиме ECB с использованием алгоритма triple-DES.
    • CKM_DES3_CBC (0x00000133) – механизм для импорта и экспорта ключей в режиме CBC с использованием алгоритма triple-DES.
    • CKM_AES_ECB (0x00001081) – механизм для импорта и экспорта ключей в режиме ECB с использованием алгоритма AES.
    • CKM_AES_CBC (0x00001082) – механизм для импорта и экспорта ключей в режиме CBC с использованием алгоритма AES.

Запускается в режимах:


Результат:    

  • CKR_ARGUMENTS_BAD – недопустимые аргументы.
  • CKR_ATTRIBUTE_READ_ONLY – невозможно установить значение атрибута, т.к. он поддерживает только чтение.
  • CKR_ATTRIBUTE_TYPE_INVALID – недопустимый тип атрибута.
  • CKR_ATTRIBUTE_VALUE_INVALID – недопустимое значение атрибута.
  • CKR_BUFFER_TOO_SMALL – вывод функции слишком велик для предоставленного буфера.
  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека еще не была инициализирована (см. C_Initialize()).
  • CKR_DEVICE_ERROR – возникла проблема с токеном и/или слотом.
  • CKR_DEVICE_MEMORY – памяти токена недостаточно для данной операции.
  • CKR_DEVICE_REMOVED – токен был изъят из слота.
  • CKR_DOMAIN_PARAMS_INVALID – недопустимые или неподдерживаемые параметры домена.
  • CKR_FUNCTION_CANCELED – функция была отменена в момент исполнения.
  • CKR_FUNCTION_FAILED – выполнение функции было прервано или она не может быть выполнена.
  • CKR_GENERAL_ERROR – общий сбой при работе с библиотекой.
  • CKR_HOST_MEMORY – компьютер, на котором запущена библиотека, не имеет достаточно памяти для выполнения функции.
  • CKR_MECHANISM_INVALID – недопустимый механизм.
  • CKR_MECHANISM_PARAM_INVALID – недопустимый параметр механизма.
  • CKR_OK – функция выполнена успешно.
  • CKR_OPERATION_ACTIVE – на устройстве уже есть активная операция, что не позволяет активизировать данную операцию.
  • CKR_PIN_EXPIRED – срок действия указанного PIN-кода истек.
  • CKR_SESSION_CLOSED – сеанс был закрыт в момент выполнения функции.
  • CKR_SESSION_HANDLE_INVALID – недопустимый дескриптор сеанса.
  • CKR_SESSION_READ_ONLY – сеанс открыт только на чтение.
  • CKR_TEMPLATE_INCOMPLETE – шаблон, указанный для создания объекта, неполон.
  • CKR_TEMPLATE_INCONSISTENT – шаблон, указанный для создания объекта, содержит конфликтующие атрибуты.
  • CKR_TOKEN_WRITE_PROTECTED – данный токен защищен от записи.
  • CKR_UNWRAPPING_KEY_HANDLE_INVALID – недопустимый указатель на ключ импорта.

Примечание: Данный аргумент возвращается только функцией C_UnwrapKey.

  • CKR_UNWRAPPING_KEY_SIZE_RANGE – размер ключа импорта лежит за пределами, поддерживаемыми библиотекой.

Примечание: Данный аргумент возвращается только функцией C_UnwrapKey.

  • CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT – данный ключ импорта невозможно использовать с указанным механизмом.

Примечание: Данный аргумент возвращается только функцией C_UnwrapKey.

  • CKR_USER_NOT_LOGGED_IN – действие не может быть выполнено, т.к. пользователь не залогинен.
  • CKR_WRAPPED_KEY_INVALID – недопустимый исходный (экспортированный) ключ.

Примечание: Данный аргумент возвращается только функцией C_UnwrapKey.

  • CKR_WRAPPED_KEY_SIZE_RANGE – размер исходного (экспортированного) ключа лежит за пределами, поддерживаемыми библиотекой.

Примечание: Данный аргумент возвращается только функцией C_UnwrapKey.

Совет: Полный список ошибок см. в приложении.

Примеры импорта ключа для GOST

Пример импорта ключа с использованием CKM_GOSTR3410_KEY_WRAP на языке C++:

<pre>// экспортное представление ключа
CK_BYTE wrappedKey[] = {0x30, 0x41, 0x30, 0x28, 0x04, 0x20, 0x65, 0xB2, 0xD5, 0x22, 0xD7, 0x74, 0xEF, 0x34, 0x39, 0xD2, 0xAC , 0x98, 0x65, 0x8B, 0xFA, 0xB5, 0x4A, 0xE7, 0xDE, 0xA2, 0x98, 0x25, 0x8E, 0xAA, 0xC6, 0x0D, 0x26, 0x17, 0x0C , 0x2C, 0xCB, 0x24, 0x04, 0x04, 0xA6, 0x2B, 0x37, 0xF0, 0xA0, 0x15, 0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01 , 0x02, 0x05, 0x01, 0x01, 0x04, 0x08, 0x1F, 0x41, 0xBD, 0x67, 0x24, 0x48, 0xBF, 0x55};
 
CK_BYTE STR_CRYPTO_PRO_GOST28147_Z[] = {0x06, 0x09, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x05, 0x01, 0x01};
const CK_ULONG STR_CRYPTO_PRO_GOST28147_Z_SIZE = sizeof(STR_CRYPTO_PRO_GOST28147_Z);
 
 
CK_OBJECT_HANDLE receiverPrivateKey= &hellip; ; // дескриптор приватного ключа Получателя
CK_OBJECT_HANDLE senderPublicKey = &hellip; ; // дескриптор публичного ключа Отправителя
 
CK_BBOOL s_TrueValue = CK_TRUE;
CK_BBOOL s_FalseValue = CK_FALSE;
 
// шаблон секретного ключа
CK_OBJECT_CLASS objectClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_GOST28147;
CK_ATTRIBUTE secretKeyTemplate[] = {
{CKA_GOST28147_PARAMS, STR_CRYPTO_PRO_GOST28147_Z, STR_CRYPTO_PRO_GOST28147_Z_SIZE},
{CKA_TOKEN, &amp;s_TrueValue, sizeof(s_TrueValue)},
{CKA_PRIVATE, &amp;s_TrueValue, sizeof(s_TrueValue)},
{CKA_CLASS, &amp;objectClass, sizeof(objectClass)},
{CKA_KEY_TYPE, &amp;keyType, sizeof(keyType)},
{CKA_DECRYPT, &amp;s_TrueValue, sizeof(s_TrueValue)}
};
 
// параметры импорта ключа
CK_GOSTR3410_KEY_WRAP_PARAMS wrapParams;
memset(&amp;wrapParams, 0, sizeof(wrapParams));
 
CK_MECHANISM mechanism;
mechanism.mechanism = CKM_GOSTR3410_KEY_WRAP;
mechanism.pParameter = &amp;wrapParams;
mechanism.ulParameterLen = sizeof(wrapParams);
 
CK_OBJECT_HANDLE hCEK = CK_INVALID_HANDLE;
 
// импорт ключа в память изделия
wrapParams.hKey = hSenderPublicKey;
 
C_UnwrapKey(hSession, &amp;mechanism, hReceiverPrivateKey, &amp;wrappedKey[0], sizeof(wrappedKey), secretKeyTemplate, 6, &amp;hCEK);</pre><p><br /></p>

Пример импорта сессионного ключа с использованием CKM_MAGMA_KEXP_15_WRAP (только для версии 2.5.13 и выше):

<pre> CK_RV rv = CKR_OK;
// экспортное представление ключа
CK_BYTE wrappedKey[] = {
0xCF, 0xD5, 0xA1, 0x2D, 0x5B, 0x81, 0xB6, 0xE1,
0xE9, 0x9C, 0x91, 0x6D, 0x07, 0x90, 0x0C, 0x6A,
0xC1, 0x27, 0x03, 0xFB, 0x3A, 0xBD, 0xED, 0x55,
0x56, 0x7B, 0xF3, 0x74, 0x2C, 0x89, 0x9C, 0x75,
0x5D, 0xAF, 0xE7, 0xB4, 0x2E, 0x3A, 0x8B, 0xD9,
};
 
// дескриптор ключа, на котором производится импорт (CKK_MAGMA_TWIN_KEY)
&nbsp; &nbsp;CK_OBJECT_HANDLE kekKeyHandle = ...;
 
// дескриптор вырабатываемого ключа
CK_OBJECT_HANDLE unwrappedKeyHandle = CK_INVALID_HANDLE;
 
// синхропосылка 4 байта (вектор инициализации)
&nbsp; &nbsp; CK_BYTE iv[] = { 0x67, 0xBE, 0xD6, 0x54, };
// механизм импорта ключа
CK_MECHANISM kexpMechanism = { CKM_MAGMA_KEXP_15_WRAP, iv, sizeof(iv) };
 
CK_BBOOL bTrue = CK_TRUE;
CK_BBOOL bFalse = CK_FALSE;
CK_KEY_TYPE keyType = CKK_MAGMA; // тип вырабатываемого ключа
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; // класс объекта - секретный ключ
 
// шаблон импортируемого ключа
CK_ATTRIBUTE unwrappedKeyTemplate[] = {
{CKA_CLASS, &amp;keyClass, sizeof(keyClass)},
{CKA_KEY_TYPE, &amp;keyType, sizeof(keyType)},
{CKA_TOKEN, &amp;bFalse, sizeof(bFalse)}, // импортируем сессионный ключ
{CKA_PRIVATE, &amp;bTrue, sizeof(bTrue)},
{CKA_EXTRACTABLE, &amp;bTrue, sizeof(bTrue)},
{CKA_SENSITIVE, &amp;bFalse, sizeof(bFalse)},
};
 
// производим импорт ключа
&nbsp; &nbsp;rv = C_UnwrapKey(hSession, &amp;kexpMechanism, kekKeyHandle, wrappedKey, sizeof(wrappedKey), unwrappedKeyTemplate, sizeof(unwrappedKeyTemplate) / sizeof(CK_ATTRIBUTE), &amp;unwrappedKeyHandle);</pre><p><br /></p>

Пример импорта сессионного ключа с использованием CKM_KUZNECHIK_KEXP_15_WRAP (только для версии 2.5.13 и выше):

<pre> CK_RV rv = CKR_OK;
// экспортное представление ключа
CK_BYTE wrappedKey[] = {
&nbsp; &nbsp; &nbsp; 0xE3, 0x61, 0x84, 0xE8, 0x4E, 0x8D, 0x73, 0x6F,
0xF3, 0x6C, 0xC2, 0xE5, 0xAE, 0x06, 0x5D, 0xC6,
0x56, 0xB2, 0x3C, 0x20, 0xF5, 0x49, 0xB0, 0x2F,
0xDF, 0xF8, 0x8E, 0x1F, 0x3F, 0x30, 0xD8, 0xC2,
0x9A, 0x53, 0xF3, 0xCA, 0x55, 0x4D, 0xBA, 0xD8,
0x0D, 0xE1, 0x52, 0xB9, 0xA4, 0x62, 0x5B, 0x32,
};
 
&nbsp; &nbsp;CK_OBJECT_HANDLE kekKeyHandle = ...; // дескриптор ключа, на котором производится импорт (CKK_KUZNECHIK_TWIN_KEY)
 
// дескриптор вырабатываемого ключа
CK_OBJECT_HANDLE unwrappedKeyHandle = CK_INVALID_HANDLE;
 
// синхропосылка 8 байта (вектор инициализации)
&nbsp; CK_BYTE iv[] = { 0x09, 0x09, 0x47, 0x2D, 0xD9, 0xF2, 0x6B, 0xE8, };
// механизм импорта ключа
CK_MECHANISM kexpMechanism = { CKM_KUZNECHIK_KEXP_15_WRAP, iv, sizeof(iv) };
 
CK_BBOOL bTrue = CK_TRUE;
CK_BBOOL bFalse = CK_FALSE;
CK_KEY_TYPE keyType = CKK_KUZNECHIK; // тип вырабатываемого ключа
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY; // класс объекта - секретный ключ
 
// шаблон импортируемого ключа
CK_ATTRIBUTE unwrappedKeyTemplate[] = {
{CKA_CLASS, &amp;keyClass, sizeof(keyClass)},
{CKA_KEY_TYPE, &amp;keyType, sizeof(keyType)},
{CKA_TOKEN, &amp;bFalse, sizeof(bFalse)}, // импортируем сессионный ключ
{CKA_PRIVATE, &amp;bTrue, sizeof(bTrue)},
{CKA_EXTRACTABLE, &amp;bTrue, sizeof(bTrue)},
{CKA_SENSITIVE, &amp;bFalse, sizeof(bFalse)},
};
 
// производим импорт ключа
&nbsp; &nbsp;rv = C_UnwrapKey(hSession, &amp;kexpMechanism, kekKeyHandle, wrappedKey, sizeof(wrappedKey), unwrappedKeyTemplate, sizeof(unwrappedKeyTemplate) / sizeof(CK_ATTRIBUTE), &amp;unwrappedKeyHandle);</pre><p><br /></p>

Пример импорта ключа в память СКЗИ с использованием CKM_MAGMA_KEXP_15_WRAP (только для версии 2.5.13 и выше):

<pre>// получаем дескрипторы приватного ключа Отправителя и публичного ключа Получателя
CK_OBJECT_HANDLE hReceiverPublicKey = &hellip; ;
CK_OBJECT_HANDLE hSenderPrivateKey = &hellip; ;
 
// Транспортное представление ключа Магма
std::vector&lt;CK_BYTE&gt; wrappedKey = {
0x30, 0x81, 0xB6, 0x04, 0x28, 0x46, 0xE1, 0xE1, 0x95, 0x32, 0x3E, 0xBA, 0xCC, 0xDF, 0x4A,
0xF6, 0xF4, 0x5D, 0x6F, 0x2E, 0x7C, 0xA2, 0xFB, 0x33, 0xC8, 0x23, 0x18, 0x09, 0x44, 0xA0,
0x70, 0x48, 0xDB, 0x10, 0x12, 0x78, 0x03, 0x8B, 0xC8, 0x11, 0xCA, 0xC2, 0xA9, 0x15, 0xAC,
0x30, 0x68, 0x30, 0x21, 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x01, 0x01, 0x30,
0x15, 0x06, 0x09, 0x2A, 0x08, 0x50, 0x30, 0x70, 0x10, 0x20, 0x10, 0x10, 0x10, 0x60, 0x82,
0xA8, 0x50, 0x30, 0x70, 0x10, 0x10, 0x20, 0x20, 0x34, 0x30, 0x00, 0x44, 0x06, 0x9C, 0x6C,
0x3E, 0x9D, 0x35, 0xC8, 0x77, 0xB2, 0x35, 0xBE, 0x01, 0x44, 0x0B, 0x1E, 0xB0, 0xC9, 0x38,
0x6B, 0xE0, 0xB8, 0x37, 0x2B, 0xCA, 0xF3, 0x00, 0x44, 0xF5, 0xCE, 0x62, 0xEB, 0xA0, 0xB6,
0x3E, 0xA8, 0x28, 0xDA, 0x9E, 0xB2, 0x1E, 0x99, 0xD6, 0xFD, 0xB7, 0x87, 0xF6, 0x77, 0x04,
0x30, 0x2C, 0xE7, 0xC8, 0x28, 0x17, 0x64, 0x94, 0x28, 0xF0, 0x0C, 0xD2, 0x22, 0x56, 0x89,
0x8F, 0xD0, 0x42, 0x0B, 0xE6, 0x75, 0x8C, 0x27, 0x9C, 0xAF, 0x53, 0xCF, 0xC7, 0x94, 0xB4,
0x48, 0xE2, 0x02, 0xDD, 0xE8, 0x63, 0xDE, 0x3D, 0x18, 0x54, 0xAA, 0x4C, 0xFF, 0x5E, 0x01,
0xE3, 0xF9, 0xF7, 0xE6, 0xCB, 0xBB
};
 
// длина транспортного представления
CK_ULONG = wrappedKey.size();
 
// механизм импорта ключа
CK_MECHANISM ckUnwrapMech;
ckUnwrapMech.mechanism = CKM_MAGMA_KEXP_15_WRAP;
ckUnwrapMech.pParameter = (CK_VOID_PTR)(&amp;hSenderPublic); // дескриптор открытого ключа Отправителя
ckUnwrapMech.ulParameterLen = sizeof(CK_OBJECT_HANDLE);
 
// класс объекта - секретный ключ
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
 
// шаблон импортируемого ключа
CK_ATTRIBUTE unwrappedKeyTemplate[] = {
{CKA_CLASS, &amp;keyClass, sizeof(keyClass)},
{CKA_KEY_TYPE, &amp;ckKeyType, sizeof(ckKeyType)},
{CKA_TOKEN, &amp;s_TrueValue, sizeof(s_TrueValue)},
{CKA_PRIVATE, &amp;s_TrueValue, sizeof(s_TrueValue)},
{CKA_EXTRACTABLE, &amp;s_TrueValue, sizeof(s_TrueValue)},
{CKA_SENSITIVE, &amp;s_FalseValue, sizeof(s_FalseValue)},
};
 
// дескриптор виртуального ключа
hVirtualSecretKey = CK_INVALID_HANDLE;
 
// производим импорт ключа на закрытом ключа Получателя
ASSERT_EQ(CKR_OK, Functions()-&gt;C_UnwrapKey(hSession, &amp;ckUnwrapMech, hReceiverPrivate, wrappedKey.data(), wrappedKeySize, unwrappedKeyTemplate, ARRAYSIZE(unwrappedKeyTemplate), &amp;hVirtualSecretKey));</pre><p><br /></p>

Пример импорта ключа в память СКЗИ с использованием CKM_KUZNECHIK_KEXP_15_WRAP (только для версии 2.5.13 и выше):

<pre>// получаем дескрипторы приватного ключа Отправителя и публичного ключа Получателя
CK_OBJECT_HANDLE hReceiverPublicKey = &hellip; ;
CK_OBJECT_HANDLE hSenderPrivateKey = &hellip; ;
 
// Транспортное представление ключа Кузнечик
std::vector&lt;CK_BYTE&gt; wrappedKey = {
0x30, 0x81, 0xBE, 0x04, 0x30, 0xB9, 0x65, 0x29, 0x2D, 0x28, 0xD2, 0x21, 0x95, 0x39, 0x6A, 0x4F, 0x46,
0x94, 0x61, 0x23, 0x9E, 0x9D, 0x2F, 0x6C, 0x5C, 0x91, 0x4F, 0x5C, 0x21, 0x57, 0x90, 0xB9, 0x36, 0x06,
0x85, 0x9C, 0xA6, 0xF1, 0x22, 0xC1, 0x30, 0x37, 0xE4, 0x85, 0xDE, 0x4A, 0x00, 0x86, 0x21, 0x23, 0x8D,
0x02, 0x93, 0x30, 0x68, 0x30, 0x21, 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x01, 0x01, 0x01, 0x30,
0x15, 0x69, 0x2A, 0x85, 0x03, 0x07, 0x01, 0x02, 0x01, 0x01, 0x02, 0x06, 0x08, 0x2A, 0x85, 0x03, 0x07,
0x01, 0x01, 0x02, 0x02, 0x03, 0x43, 0x00, 0x04, 0x40, 0x05, 0x73, 0xBD, 0x1F, 0xB0, 0xB1, 0x89, 0x2D,
0xE9, 0x9C, 0xAA, 0x27, 0x4A, 0xA1, 0xEC, 0x42, 0x3D, 0x68, 0x9C, 0x9C, 0x42, 0xA9, 0xC9, 0xE9, 0xB3,
0xDC, 0xB0, 0x4D, 0xD5, 0xFF, 0xF0, 0x82, 0xAD, 0xBD, 0xBF, 0xE3, 0x9C, 0x14, 0x79, 0xA4, 0x27, 0x3D,
0x37, 0xC6, 0x82, 0xCA, 0x81, 0xFA, 0xC5, 0x14, 0xEF, 0xF7, 0x22, 0xE0, 0x1C, 0xCB, 0x46, 0x73, 0x10,
0xF7, 0x07, 0x52, 0x20, 0xB7, 0x04, 0x20, 0xF3, 0xC5, 0xC4, 0x0B, 0x98, 0xAB, 0xD0, 0x38, 0x8C, 0xFE,
0x0D, 0x8E, 0xE1, 0x85, 0xAC, 0x2B, 0xAB, 0x84, 0x81, 0x31, 0x23, 0xB4, 0x35, 0x19, 0x08, 0x28, 0x54,
0x3E, 0xF3, 0x4D, 0xE0, 0x09
};
 
// длина транспортного представления
CK_ULONG = wrappedKey.size();
 
// механизм импорта ключа
CK_MECHANISM ckUnwrapMech;
ckUnwrapMech.mechanism = CKM_KUZNECHIK_KEXP_15_WRAP;
ckUnwrapMech.pParameter = (CK_VOID_PTR)(&amp;hSenderPublic); // дескриптор открытого ключа Отправителя
ckUnwrapMech.ulParameterLen = sizeof(CK_OBJECT_HANDLE);
 
// класс объекта - секретный ключ
CK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;
 
// шаблон импортируемого ключа
CK_ATTRIBUTE unwrappedKeyTemplate[] = {
{CKA_CLASS, &amp;keyClass, sizeof(keyClass)},
{CKA_KEY_TYPE, &amp;ckKeyType, sizeof(ckKeyType)},
{CKA_TOKEN, &amp;s_TrueValue, sizeof(s_TrueValue)},
{CKA_PRIVATE, &amp;s_TrueValue, sizeof(s_TrueValue)},
{CKA_EXTRACTABLE, &amp;s_TrueValue, sizeof(s_TrueValue)},
{CKA_SENSITIVE, &amp;s_FalseValue, sizeof(s_FalseValue)},
};
 
// дескриптор виртуального ключа
hVirtualSecretKey = CK_INVALID_HANDLE;
 
// производим импорт ключа на закрытом ключа Получателя
ASSERT_EQ(CKR_OK, Functions()-&gt;C_UnwrapKey(hSession, &amp;ckUnwrapMech, hReceiverPrivate, wrappedKey.data(), wrappedKeySize, unwrappedKeyTemplate, ARRAYSIZE(unwrappedKeyTemplate), &amp;hVirtualSecretKey));</pre><p><br /></p>

C_DeriveKey

CK_RV C_DeriveKey(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hBaseKey, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulAttributeCount, 

CK_OBJECT_HANDLE_PTR phKey)


Параметры:    

  • hSession (in) – дескриптор сеанса.
  • pMechanism (in) – указатель на механизм.
  • hBaseKey (in) – дескриптор закрытого ключа отправителя или получателя.
  • pTemplate (in) – указатель на шаблон объекта ключа согласования.
  • ulAttributeCount (in) – количество атрибутов в шаблоне.
  • phKey (in/out) – ключ согласования/экспортированный сессионный ключ.

Вырабатывает ключ согласования или сессионный ключ (в зависимости от апплета, с которым происходит работа и используемого механизма).

Особенности приложений:

  • Приложение GOST версии 2.5.5, 2.5.9

    Поддерживаемые механизмы:

    • CKM_GOSTR3410_DERIVE (0x00001204) – механизм для выработки ключа согласования, соответствующий стандарту ГОСТ Р 34.10–2001.
    • CKM_GOSTR3410_2012_DERIVE (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x007) – механизм для выработки ключа согласования, соответствующий стандарту ГОСТ Р 34.10–2012.
    • CKM_GOSTR3410_12_DERIVE – псевдоним для CKM_CKM_GOSTR3410_2012_DERIVE
  • Приложение GOST версии 2.5.13

    Поддерживаемые механизмы:

    • CKM_GOSTR3410_DERIVE (0x00001204) – механизм для выработки ключа согласования, соответствующий стандарту ГОСТ Р 34.10–2001.
    • CKM_GOSTR3410_2012_DERIVE (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x007) – механизм для выработки ключа согласования, соответствующий стандарту ГОСТ Р 34.10–2012.
    • CKM_GOSTR3410_12_DERIVE – псевдоним для CKM_CKM_GOSTR3410_2012_DERIVE
    • CKM_KDF_TREE_GOSTR3411_2012_256 (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x02AUL) - механизм диверсификации ключей
    • CKM_VKO_GOSTR3410_2012_512 (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x038UL) - механизм для выработки ключа согласования, соответствующий стандарту ГОСТ Р 34.10–2018.
    • CKM_GOST_KEG (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x039UL) - механизм для выработки ключа согласования длиной 512 бит, соответствующий стандарту ГОСТ Р 34.10–2018.
  • Приложение PKI

    Поддерживаемые механизмы:

    • CKM_TLS_MASTER_KEY_DERIVE (0x00000375) – механизм для выработки 48-байтного ключа из другого 48-байтного ключа, используемый при создании master_secret ключей для протокола TLS 1.0.
    • CKM_TLS_KEY_AND_MAC_DERIVE (0x00000376) – механизм для выработки ключа согласования из master_secret и случайных данных.
    • CKM_TLS_MASTER_KEY_DERIVE_DH (0x00000377) – механизм для выработки 48-байтного ключа из другого ключа произвольного размера, используемый при создании master_secret ключей для протокола TLS 1.0.
    • CKM_TLS_PRF (0x00000378) – механизм для генерации псевдослучайных данных произвольной длины.
    • CKM_ECDH1_DERIVE (0x00001050) – механизм для генерации ключа согласования, основывающийся на эллиптических кривых и алгоритме Диффи-Хеллмана.

Запускается в режимах:


Результат:    

  • CKR_ARGUMENTS_BAD – недопустимые аргументы.
  • CKR_ATTRIBUTE_READ_ONLY – невозможно установить значение атрибута, т.к. он поддерживает только чтение.
  • CKR_ATTRIBUTE_TYPE_INVALID – недопустимый тип атрибута.
  • CKR_ATTRIBUTE_VALUE_INVALID – недопустимое значение атрибута.
  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека еще не была инициализирована (см. C_Initialize()).
  • CKR_DEVICE_ERROR – возникла проблема с токеном и/или слотом.
  • CKR_DEVICE_MEMORY – памяти токена недостаточно для данной операции.
  • CKR_DEVICE_REMOVED – токен был изъят из слота.
  • CKR_DOMAIN_PARAMS_INVALID – недопустимые или неподдерживаемые параметры домена.
  • CKR_FUNCTION_CANCELED – функция была отменена в момент исполнения.
  • CKR_FUNCTION_FAILED – выполнение функции было прервано или она не может быть выполнена.
  • CKR_GENERAL_ERROR – общий сбой при работе с библиотекой.
  • CKR_HOST_MEMORY – компьютер, на котором запущена библиотека, не имеет достаточно памяти для выполнения функции.
  • CKR_KEY_HANDLE_INVALID – недопустимый дескриптор ключа.
  • CKR_KEY_SIZE_RANGE – размер ключа лежит за пределами, поддерживаемыми библиотекой.
  • CKR_KEY_TYPE_INCONSISTENT – данный ключ невозможно использовать с указанным механизмом.
  • CKR_MECHANISM_INVALID – недопустимый механизм.
  • CKR_MECHANISM_PARAM_INVALID – недопустимый параметр механизма.
  • CKR_OK – функция выполнена успешно.
  • CKR_OPERATION_ACTIVE – на устройстве уже есть активная операция, что не позволяет активизировать данную операцию.
  • CKR_PIN_EXPIRED – срок действия указанного PIN-кода истек.
  • CKR_SESSION_CLOSED – сеанс был закрыт в момент выполнения функции.
  • CKR_SESSION_HANDLE_INVALID – недопустимый дескриптор сеанса.
  • CKR_SESSION_READ_ONLY – сеанс открыт только на чтение.
  • CKR_TEMPLATE_INCOMPLETE – шаблон, указанный для создания объекта, неполон.
  • CKR_TEMPLATE_INCONSISTENT – шаблон, указанный для создания объекта, содержит конфликтующие атрибуты.
  • CKR_TOKEN_WRITE_PROTECTED – данный токен защищен от записи.
  • CKR_USER_NOT_LOGGED_IN – действие не может быть выполнено, т.к. пользователь не залогинен.

Совет: Полный список ошибок см. в приложении.

Примеры согласования ключей для GOST

Пример диверсификации сессионного ключа по CKM_KDF_TREE_GOSTR3411_2012_256 (только версии 2.5.13 и выше):

<pre>CK_BYTE label[] = { 0x26, 0xbd, 0xb8, 0x78, };
CK_BYTE seed[] = { 0xaf, 0x21, 0x43, 0x41, 0x45, 0x65, 0x63, 0x78, };
 
// параметры выработки ключа
CK_KDF_TREE_GOST_PARAMS deriveParams = {
sizeof(label), label,
sizeof(seed), seed,
1,
64,
32
};
 
// механизм выработки ключа
CK_MECHANISM deriveMechanism = { CKM_KDF_TREE_GOSTR3411_2012_256, &amp;deriveParams, sizeof(deriveParams) };
 
// шаблон вырабатываемого ключа
CK_ATTRIBUTE derivedKeyTemplate[] = {
{CKA_CLASS, &amp;keyClass, sizeof(keyClass)},
{CKA_KEY_TYPE, &amp;keyTypeD, sizeof(keyType)},
{CKA_TOKEN, &amp;bFalse, sizeof(bFalse)},
{CKA_PRIVATE, &amp;bTrue, sizeof(bTrue)},
{CKA_EXTRACTABLE, &amp;bTrue, sizeof(bTrue)},
{CKA_SENSITIVE, &amp;bFalse, sizeof(bFalse)},
};
 
// ...
// получение дескриптора сессии
// аутентификации Пользователем
// получение дескриптора keyHandle ключа, на котором предполагается производить выработку
// ...
 
C_DeriveKey(hSession, &amp;deriveMechanism, keyHandle, derivedKeyTemplate, sizeof(derivedKeyTemplate) / sizeof(CK_ATTRIBUTE), &amp;derivedKeyHandle));</pre><p><br /></p>

Пример согласования ключей по CKM_GOST_KEG (только для версии 2.5.13 и выше):

<pre> /// ...
/// Предполагается, что уже есть дескриптор сессии, произведена аутентификация Пользователем.
/// Также есть дескриптор закрытого ключа Отправителя (senderPrivateKey) и значение открытого ключа Получателя (pPublicData)
/// ...
// класс объекта - секретный ключ
CK_ULONG secretKeyClass = CKO_SECRET_KEY;
// тип вырабатываемого ключа
CK_KEY_TYPE keyType = CKK_MAGMA_TWIN_KEY;
 
// шаблон вырабатываемого ключа согласования
CK_ATTRIBUTE derivedKeyTemplate[] = {
{CKA_CLASS, &amp;secretKeyClass, sizeof(secretKeyClass)}, // Класс - секретный ключ
{CKA_TOKEN, &amp;s_FalseValue, sizeof(s_FalseValue)}, // Ключ является объектом сессии
{CKA_KEY_TYPE, &amp;keyType, sizeof(keyType)}, // Тип ключа - двойственный ключ Магма
{CKA_ENCRYPT,&amp;s_TrueValue, sizeof(s_TrueValue)}, // На ключе можно шифровать
{CKA_DECRYPT, &amp;s_TrueValue, sizeof(s_TrueValue)} // На ключе можно расшифровывать
};
 
// дескриптор вырабатываемого ключа
CK_OBJECT_HANDLE hDerivedKey = CK_INVALID_HANDLE;
 
// параметры механизма
CK_ECDH1_DERIVE_PARAMS keg256DeriveParams;
 
// механизм выработки ключа
CK_MECHANISM gostKegDerifivationMech = { CKM_GOST_KEG, &amp;keg256DeriveParams, sizeof(keg256DeriveParams) };
 
// ключевой материал
CK_BYTE ukm[32] = {
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
};
 
keg256DeriveParams.kdf = CKD_NULL;
keg256DeriveParams.ulSharedDataLen = (CK_ULONG)sizeof(ukm);
keg256DeriveParams.pSharedData = (CK_BYTE_PTR)&amp;ukm[0];
keg256DeriveParams.ulPublicDataLen = ulPublicDataLen;
keg256DeriveParams.pPublicData = pPublicData;
 
// производим выработку ключа согласования
C_DeriveKey(hSession, &amp;gostKegDerifivationMech, senderPrivateKey, derivedKeyTemplate, sizeof(derivedKeyTemplate) / sizeof(CK_ATTRIBUTE), &amp;hDerivedKey);</pre><p><br /></p>

Пример выработки ключа согласования с использованием дескриптора открытого ключа Получателя для ключей ГОСТ Р 34.10–2001ГОСТ Р 34.10–2012 на языке C:

<pre>static CK_BYTE id_Gost28147_89_CryptoPro_A_ParamSet[] = { 0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x1F, 0x01 };
 
CK_BBOOL bTrue = CK_TRUE;
CK_BBOOL bFalse = CK_FALSE;
 
// результат выполнения функции
CK_RV rv = CKR_OK;
 
// дескриптор сессии
CK_SESSION_HANDLE pkcs11SessionHandle;
 
// дескриптор закрытого ключа ключевой пары Отправителя
CK_OBJECT_HANDLE hPrivateKey;
 
// дескриптор открытого ключа Получателя
CK_OBJECT_HANDLE hPublicKey;
 
// механизм диверсификации ключа
CK_EC_KDF_TYPE kdf = CKD_NULL;
 
CK_BYTE ukm[] = {1, 2, 3, 4, 5, 6, 7, 8};
 
// дескриптор ключа согласования PKCS#11
CK_OBJECT_HANDLE hDerivedKey;
 
// ...
// генерация ключевой пары Отправителя
// получение дескриптора открытого ключа Получателя
// ...
 
// параметры для создания ключа согласования
JC_KT2_GOSTR3410_DERIVE_PARAMS jcCT2DeriveParams;
jcCT2DeriveParams.kdf = kdf;
jcCT2DeriveParams.hPublicKey = hPublicKey;
jcCT2DeriveParams.pUKM = CK_BYTE_PTR(&amp;ukm[0]);
jcCT2DeriveParams.ulUKMLen = 8;
 
CK_MECHANISM ckDeriveMechanism = {CKM_GOSTR3410_DERIVE, &amp;jcCT2DeriveParams, sizeof(jcCT2DeriveParams)};
 
// шаблон ключа согласования
CK_ULONG secretKeyClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_GOST28147;
 
CK_ATTRIBUTE derivedKeyTemplate[] = {
{CKA_CLASS, &amp;secretKeyClass, sizeof(secretKeyClass)},
{CKA_TOKEN, &amp;bFalse, sizeof(bFalse)},
{CKA_GOST28147_PARAMS, id_Gost28147_89_CryptoPro_A_ParamSet, sizeof(id_Gost28147_89_CryptoPro_A_ParamSet)},
{CKA_KEY_TYPE, &amp;keyType, sizeof(keyType)},
{CKA_WRAP, &amp;bTrue, sizeof(bTrue)},
{CKA_UNWRAP, &amp;bTrue, sizeof(bTrue)}
};
 
rv = C_DeriveKey(pkcs11SessionHandle,
&amp;ckDeriveMechanism,
hPrivateKey,
derivedKeyTemplate, sizeof(derivedKeyTemplate)/sizeof(CK_ATTRIBUTE),
&amp;hDerivedKey);
if(rv != CKR_OK)
{
PrintError(&quot;C_DeriveKey&quot;, rv);
return;
}</pre><p><br /></p>

Пример выработки ключа с использованием значения открытого ключа Получателя для ключей ГОСТ Р 34.10–2012 на языке C:

<pre>static CK_BYTE id_Gost28147_89_CryptoPro_A_ParamSet[] = { 0x06, 0x07, 0x2A, 0x85, 0x03, 0x02, 0x02, 0x1F, 0x01 };
 
// значение открытого ключа Получателя, ГОСТР 34.10-2012
CK_BYTE publicKeyValue[] =
{
0x41, 0x40, 0x90, 0x36, 0x0E, 0x5E, 0x61, 0x82, 0x1C, 0xC6, 0xD6, 0x91, 0x11, 0x04, 0x71, 0xBB,
0xF0, 0xE3, 0x5F, 0x31, 0xDF, 0x94, 0x79, 0x7E, 0xE9, 0x5D, 0x24, 0xEB, 0x67, 0xC4, 0x38, 0xA1,
0xC5, 0xAA, 0x23, 0xC2, 0xFF, 0x33, 0xBA, 0x95, 0x27, 0x79, 0x36, 0x6E, 0x9A, 0x9F, 0xC6, 0x76,
0xF2, 0x8C, 0x2B, 0x6A, 0xC2, 0x5D, 0x61, 0x7F, 0xC1, 0xF3, 0x10, 0x50, 0x34, 0x35, 0x67, 0x1B
};
 
CK_BBOOL bTrue = CK_TRUE;
CK_BBOOL bFalse = CK_FALSE;
 
// результат выполнения функции
CK_RV rv = CKR_OK;
 
// дескриптор сессии
CK_SESSION_HANDLE pkcs11SessionHandle;
 
// дескриптор закрытого ключа ключевой пары Отправителя
CK_OBJECT_HANDLE hPrivateKey;
 
// механизм диверсификации ключа
CK_EC_KDF_TYPE kdf = CKD_NULL;
 
CK_BYTE ukm[] = {1, 2, 3, 4, 5, 6, 7, 8};
 
// дескриптор ключа согласования PKCS#11
CK_OBJECT_HANDLE hDerivedKey;
 
// ...
// генерация ключевой пары Отправителя
// ...
 
// параметры для создания ключа согласования
// представлены в соответствии с рекомендациями ТК26
uint32_t tc26DeriveParams[21] = {0};
tc26DeriveParams[0] = kdf;
tc26DeriveParams[1] = sizeof(publicKeyValue);
memcpy(tc26DeriveParams + 2, &amp;publicKeyValue[0], sizeof(publicKeyValue));
tc26DeriveParams[18] = 8;
memcpy(tc26DeriveParams + 19, &amp;ukm[0], 8);
 
CK_MECHANISM deriveMechanism = {CKM_GOSTR3410_2012_DERIVE, &amp;tc26DeriveParams, sizeof(tc26DeriveParams)};
 
// шаблон ключа согласования
CK_ULONG secretKeyClass = CKO_SECRET_KEY;
CK_KEY_TYPE keyType = CKK_GOST28147;
CK_ATTRIBUTE derivedKeyTemplate[] = {
{CKA_CLASS, &amp;secretKeyClass, sizeof(secretKeyClass)},
{CKA_TOKEN, &amp;bFalse, sizeof(bFalse)},
{CKA_GOST28147_PARAMS, id_Gost28147_89_CryptoPro_A_ParamSet, sizeof(id_Gost28147_89_CryptoPro_A_ParamSet)},
{CKA_KEY_TYPE, &amp;keyType, sizeof(keyType)},
{CKA_WRAP, &amp;bTrue, sizeof(bTrue)},
{CKA_UNWRAP, &amp;bTrue, sizeof(bTrue)}
};
 
rv = C_DeriveKey(pkcs11SessionHandle,
&amp;ckDeriveMechanism,
hPrivateKey,
derivedKeyTemplate, sizeof(derivedKeyTemplate)/sizeof(CK_ATTRIBUTE),
&amp;hDerivedKey);
if(rv != CKR_OK)
{
PrintError(&quot;C_DeriveKey&quot;, rv);
return;
}</pre>