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#11CK_OBJECT_HANDLE pkcs11SessionKeyHandle;// функция генерирует ключ, используя заданный шаблонrv = C_GenerateKey(pkcs11SessionHandle, &pkcs11GenKeyMechanism, pkcs11SessionKeyTemplate, sizeof(pkcs11SessionKeyTemplate)/sizeof(CK_ATTRIBUTE), &pkcs11SessionKeyHandle);if(rv != CKR_OK){ PrintError("C_GenerateKey", 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; // на ключе можно расшифровывать CK_BBOOL extractable = CK_TRUE; // Ключ может быть экспортирован CK_BBOOL sensitive = CK_TRUE; // Ключ является чувствительным CK_KEY_TYPE keyType = CKK_MAGMA; // CKK_KUZNECHIK // атрибуты ключа CK_ATTRIBUTE keyTemplate[] = { { CKA_CLASS, &keyClass, sizeof(keyClass) }, { CKA_KEY_TYPE, &keyType, sizeof(keyType) }, { CKA_TOKEN, &token, sizeof(token) }, { CKA_PRIVATE, &privateKey, sizeof(privateKey) }, { CKA_ENCRYPT, &encrypt, sizeof(encrypt) }, { CKA_DECRYPT, &decrypt, sizeof(decrypt) }, { CKA_EXTRACTABLE, &extractable, sizeof(extractable) }, { CKA_SENSITIVE, &sensitive, sizeof(sensitive) } }; // Механизм генерации ключа CK_MECHANISM mechanism; mechanism.mechanism = CKM_MAGMA_KEY_GEN; // CKM_KUZNECHIK_KEY_GEN mechanism.pParameter = NULL_PTR; mechanism.ulParameterLen = 0; // Генерация ключа rv = C_GenerateKey(session, &mechanism, keyTemplate, sizeof(keyTemplate) / sizeof(CK_ATTRIBUTE), &hKey); if (rv != CKR_OK) { PrintError("C_GenerateKey", rv); }</pre>C_GenerateKeyPair
CK_RV C_GenerateKeyPair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_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_GENid-GostR3411-94-CryptoProParamSetГОСТ Р 34.10–2012 (длина ключа 256 бит)
CKM_GOSTR3410_256_KEY_PAIR_GENid-tc26-gost3411-12-256ГОСТ Р 34.10–2018 (длина ключа 512 бит)
CKM_GOSTR3410_512_KEY_PAIR_GENid-tc26-gost3411-12-512
Совет: Значения атрибута |
Приложение 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[] = "Private Key GOST R 34.10-2001 256";CK_KEY_TYPE privKeyType = CKK_GOSTR3410;// шаблон закрытого ключаCK_ATTRIBUTE privKeyTemplate[] ={ {CKA_CLASS, &privKeyClass, sizeof(privKeyClass)}, // класс {CKA_KEY_TYPE, &privKeyType, sizeof(privKeyType)}, // тип ключа {CKA_TOKEN, (CK_VOID_PTR) &bTrue, sizeof(bTrue)}, // объект хранится в токене {CKA_LABEL, (CK_VOID_PTR) privKeyLabel, (CK_ULONG) strlen(privKeyLabel)}, // метка закрытого ключа {CKA_PRIVATE, &bTrue, sizeof(bTrue) }, // не виден без ввода PIN-кода пользователя};// параметры шаблона открытого ключаCK_OBJECT_CLASS pubKeyClass = CKO_PUBLIC_KEY;CK_UTF8CHAR pubKeyLabel[] = "Public Key GOST R 34.10-2001 256";CK_KEY_TYPE pubKeyType = CKK_GOSTR3410;// шаблон открытого ключаCK_ATTRIBUTE pubKeyTemplate[] ={ {CKA_CLASS, &privKeyClass, sizeof(privKeyClass)}, // класс {CKA_KEY_TYPE, &privKeyType, sizeof(privKeyType)}, // тип ключа {CKA_TOKEN, (CK_VOID_PTR) &bTrue, sizeof(bTrue)}, // объект хранится в токене {CKA_LABEL, (CK_VOID_PTR) pubKeyLabel, (CK_ULONG) strlen(pubKeyLabel)}, // метка закрытого ключа {CKA_PRIVATE, &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#11CK_OBJECT_HANDLE pubKeyHandle, privKeyHandle;// функция генерирует ключевую паруrv = C_GenerateKeyPair(session, &mechanism, pubKeyTemplate, sizeof(pubKeyTemplate)/sizeof(CK_ATTRIBUTE), privKeyTemplate, sizeof(privKeyTemplate)/sizeof(CK_ATTRIBUTE), &pubKeyHandle, &privKeyHandle);if(rv != CKR_OK){ PrintError("C_GenerateKeyPair", 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, &pubkeyClass, sizeof(pubkeyClass) }, // Класс - открытый ключ {CKA_KEY_TYPE, &keyType2012, sizeof(keyType2012) }, // Тип ключа - ГОСТ Р 34.10-2012(512) {CKA_TOKEN, &bTrue, sizeof(bTrue) }, // Ключ является объектом токена {CKA_PRIVATE, &bFalse, sizeof(bFalse) }, // Ключ доступен без аутентификации на токене {CKA_VERIFY, &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, &privkeyClass, sizeof(privkeyClass) }, // Класс - закрытый ключ {CKA_KEY_TYPE, &keyType2012, sizeof(keyType2012) }, // Тип ключа - ГОСТ Р 34.10-2012(512) {CKA_TOKEN, &bTrue, sizeof(bTrue) }, // Ключ является объектом токена {CKA_PRIVATE, &bTrue, sizeof(bTrue) }, // Ключ доступен только после аутентификации на токене {CKA_SIGN, &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()->C_GenerateKeyPair(SessionHandle(), &asymKeyMechanism512, PublicKey512Template, sizeof(PublicKey512Template) / sizeof(CK_ATTRIBUTE), PrivateKey512Template, sizeof(PrivateKey512Template) / sizeof(CK_ATTRIBUTE), &publicKey512, &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 – недопустимый указатель на ключ экспорта
Примечание: Данный аргумент возвращается только функцией |
CKR_WRAPPING_KEY_SIZE_RANGE– размер ключа экспорта лежит за пределами, поддерживаемыми библиотекой.
Примечание: Данный аргумент возвращается только функцией |
CKR_WRAPPING_KEY_TYPE_INCONSISTENT– данный ключ экспорта невозможно использовать с указанным механизмом.
Примечание: Данный аргумент возвращается только функцией |
Совет: Полный список ошибок см. в приложении. |
Примеры экспорта ключа для GOST
Пример экспорта ключа с использованием CKM_GOSTR3410_KEY_WRAP и виртуального секретного ключа на языке C++:
<pre>// получаем дескриптор сессииCK_SESSION_HANDLE hSession = … ;// режим ПользователяCK_UTF8CHAR pin[] = "1234567890";C_Login(hSession, CKU_USER, pin, strlen(pin));// получаем дескрипторы приватного ключа Отправителя и публичного ключа ПолучателяCK_OBJECT_HANDLE hReceiverPublicKey = … ;CK_OBJECT_HANDLE hSenderPrivateKey = … ;CK_OBJECT_CLASS ckaClass = CKO_SECRET_KEY;CK_BYTE ckaId[] = "VSKO_ID"; // "VSKO_ID"// атрибуты поиска виртуального ключаCK_ATTRIBUTE searchAtt[] = { {CKA_CLASS, &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, &hVirtualSecretKey, 1, &ulObjectsCount);C_FindObjectsFinal(hSession);// параметры экспорта ключаCK_GOSTR3410_KEY_WRAP_PARAMS wrapParams;memset(&wrapParams, 0, sizeof(wrapParams));wrapParams.hKey = hSenderPrivateKey;CK_MECHANISM ckWrapMechanism;ckWrapMechanism.mechanism = CKM_GOSTR3410_KEY_WRAP;ckWrapMechanism.pParameter = &wrapParams;ckWrapMechanism.ulParameterLen = sizeof(wrapParams);// получаем требуемый размер для экспортированного представленияCK_ULONG wrappedKeySize = 0;C_WrapKey(hSession, &ckWrapMechanism, hReceiverPublicKey, hVirtualSecretKey, NULL, &wrappedKeySize);// генерируем и экспортируем ключ hVirtualSecretKeystd::vector<CK_BYTE> wrappedKey(wrappedKeySize);C_WrapKey(hSession, &ckWrapMechanism, hReceiverPublicKey, hVirtualSecretKey, &wrappedKey[0], &wrappedKeySize);</pre><p><br /></p>Пример экспорта виртуального секретного ключа по CKM_MAGMA_KEXP_15_WRAP на языке C++:
<pre>CK_OBJECT_CLASS objectClass = CKO_SECRET_KEY;CK_BYTE ckaId[] = "VSKO_ID";// шаблон поиска виртуального ключаCK_ATTRIBUTE searchAtt[] = { {CKA_CLASS, &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, &hVirtualSecretKey, 1, &ulObjectsCount);C_FindObjectsFinal(hSession);// получаем дескрипторы приватного ключа Отправителя и публичного ключа ПолучателяCK_OBJECT_HANDLE hReceiverPublicKey = … ;CK_OBJECT_HANDLE hSenderPrivateKey = … ;// механизм экспорта ключаCK_MECHANISM ckWrapMech;ckWrapMech.mechanism = CKM_MAGMA_KEXP_15_WRAP;ckWrapMech.pParameter = (CK_VOID_PTR)(&hSenderPrivate);ckWrapMech.ulParameterLen = sizeof(CK_OBJECT_HANDLE);// размер экспортного представления ключаCK_ULONG wrappedKeySize; // определяем длину экспортного представленияC_WrapKey(hSession, &ckWrapMech, hReceiverPublic, hVirtualSecretKey, NULL_PTR, &wrappedKeySize);// выделяем память для экспортного представления ключаstd::vector<CK_BYTE> wrappedKey(wrappedKeySize);// производим экспорт ключаC_WrapKey(hSession, &ckWrapMech, hReceiverPublic, hVirtualSecretKey, wrappedKey.data(), &wrappedKeySize);</pre><p><br /></p>Пример экспорта виртуального секретного ключа по CKM_KUZNECHIK_KEXP_15_WRAP на языке C++:
<pre>CK_OBJECT_CLASS objectClass = CKO_SECRET_KEY;CK_BYTE ckaId[] = "VSKO_ID";// шаблон поиска виртуального ключаCK_ATTRIBUTE searchAtt[] = { {CKA_CLASS, &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, &hVirtualSecretKey, 1, &ulObjectsCount);C_FindObjectsFinal(hSession);// получаем дескрипторы приватного ключа Отправителя и публичного ключа ПолучателяCK_OBJECT_HANDLE hReceiverPublicKey = … ;CK_OBJECT_HANDLE hSenderPrivateKey = … ;// механизм экспорта ключаCK_MECHANISM ckWrapMech;ckWrapMech.mechanism = CKM_KUZNECHIK_KEXP_15_WRAP;ckWrapMech.pParameter = (CK_VOID_PTR)(&hSenderPrivate);ckWrapMech.ulParameterLen = sizeof(CK_OBJECT_HANDLE);// размер экспортного представления ключаCK_ULONG wrappedKeySize; // определяем длину экспортного представленияC_WrapKey(hSession, &ckWrapMech, hReceiverPublic, hVirtualSecretKey, NULL_PTR, &wrappedKeySize);// выделяем память для экспортного представления ключаstd::vector<CK_BYTE> wrappedKey(wrappedKeySize);// производим экспорт ключаC_WrapKey(hSession, &ckWrapMech, hReceiverPublic, hVirtualSecretKey, wrappedKey.data(), &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, &kexpMechanism, kekKeyHandle, cekKeyHandle, NULL, &valueLength);// выделяем память для экспортного представленияstd::vector<CK_BYTE> value(valueLength);// производим экспорт ключа rv = C_WrapKey(hSession, &kexpMechanism, kekKeyHandle, cekKeyHandle, value.data(), &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, &kexpMechanism, kekKeyHandle, cekKeyHandle, NULL, &valueLength);// выделяем память для экспортного представленияstd::vector<CK_BYTE> value(valueLength); // производим экспорт ключа rv = C_WrapKey(hSession, &kexpMechanism, kekKeyHandle, cekKeyHandle, value.data(), &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 – недопустимый указатель на ключ импорта.
Примечание: Данный аргумент возвращается только функцией |
CKR_UNWRAPPING_KEY_SIZE_RANGE– размер ключа импорта лежит за пределами, поддерживаемыми библиотекой.
Примечание: Данный аргумент возвращается только функцией |
CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT– данный ключ импорта невозможно использовать с указанным механизмом.
Примечание: Данный аргумент возвращается только функцией |
CKR_USER_NOT_LOGGED_IN– действие не может быть выполнено, т.к. пользователь не залогинен.CKR_WRAPPED_KEY_INVALID– недопустимый исходный (экспортированный) ключ.
Примечание: Данный аргумент возвращается только функцией |
CKR_WRAPPED_KEY_SIZE_RANGE– размер исходного (экспортированного) ключа лежит за пределами, поддерживаемыми библиотекой.
Примечание: Данный аргумент возвращается только функцией |
Совет: Полный список ошибок см. в приложении. |
Примеры импорта ключа для 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= … ; // дескриптор приватного ключа ПолучателяCK_OBJECT_HANDLE senderPublicKey = … ; // дескриптор публичного ключа Отправителя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, &s_TrueValue, sizeof(s_TrueValue)}, {CKA_PRIVATE, &s_TrueValue, sizeof(s_TrueValue)}, {CKA_CLASS, &objectClass, sizeof(objectClass)}, {CKA_KEY_TYPE, &keyType, sizeof(keyType)}, {CKA_DECRYPT, &s_TrueValue, sizeof(s_TrueValue)}};// параметры импорта ключаCK_GOSTR3410_KEY_WRAP_PARAMS wrapParams;memset(&wrapParams, 0, sizeof(wrapParams));CK_MECHANISM mechanism;mechanism.mechanism = CKM_GOSTR3410_KEY_WRAP;mechanism.pParameter = &wrapParams;mechanism.ulParameterLen = sizeof(wrapParams);CK_OBJECT_HANDLE hCEK = CK_INVALID_HANDLE;// импорт ключа в память изделияwrapParams.hKey = hSenderPublicKey;C_UnwrapKey(hSession, &mechanism, hReceiverPrivateKey, &wrappedKey[0], sizeof(wrappedKey), secretKeyTemplate, 6, &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) CK_OBJECT_HANDLE kekKeyHandle = ...; // дескриптор вырабатываемого ключа CK_OBJECT_HANDLE unwrappedKeyHandle = CK_INVALID_HANDLE; // синхропосылка 4 байта (вектор инициализации) 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, &keyClass, sizeof(keyClass)}, {CKA_KEY_TYPE, &keyType, sizeof(keyType)}, {CKA_TOKEN, &bFalse, sizeof(bFalse)}, // импортируем сессионный ключ {CKA_PRIVATE, &bTrue, sizeof(bTrue)}, {CKA_EXTRACTABLE, &bTrue, sizeof(bTrue)}, {CKA_SENSITIVE, &bFalse, sizeof(bFalse)}, }; // производим импорт ключа rv = C_UnwrapKey(hSession, &kexpMechanism, kekKeyHandle, wrappedKey, sizeof(wrappedKey), unwrappedKeyTemplate, sizeof(unwrappedKeyTemplate) / sizeof(CK_ATTRIBUTE), &unwrappedKeyHandle);</pre><p><br /></p>Пример импорта сессионного ключа с использованием CKM_KUZNECHIK_KEXP_15_WRAP (только для версии 2.5.13 и выше):
<pre> CK_RV rv = CKR_OK; // экспортное представление ключа CK_BYTE wrappedKey[] = { 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, }; CK_OBJECT_HANDLE kekKeyHandle = ...; // дескриптор ключа, на котором производится импорт (CKK_KUZNECHIK_TWIN_KEY) // дескриптор вырабатываемого ключа CK_OBJECT_HANDLE unwrappedKeyHandle = CK_INVALID_HANDLE; // синхропосылка 8 байта (вектор инициализации) 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, &keyClass, sizeof(keyClass)}, {CKA_KEY_TYPE, &keyType, sizeof(keyType)}, {CKA_TOKEN, &bFalse, sizeof(bFalse)}, // импортируем сессионный ключ {CKA_PRIVATE, &bTrue, sizeof(bTrue)}, {CKA_EXTRACTABLE, &bTrue, sizeof(bTrue)}, {CKA_SENSITIVE, &bFalse, sizeof(bFalse)}, }; // производим импорт ключа rv = C_UnwrapKey(hSession, &kexpMechanism, kekKeyHandle, wrappedKey, sizeof(wrappedKey), unwrappedKeyTemplate, sizeof(unwrappedKeyTemplate) / sizeof(CK_ATTRIBUTE), &unwrappedKeyHandle);</pre><p><br /></p>Пример импорта ключа в память СКЗИ с использованием CKM_MAGMA_KEXP_15_WRAP (только для версии 2.5.13 и выше):
<pre>// получаем дескрипторы приватного ключа Отправителя и публичного ключа ПолучателяCK_OBJECT_HANDLE hReceiverPublicKey = … ;CK_OBJECT_HANDLE hSenderPrivateKey = … ;// Транспортное представление ключа Магмаstd::vector<CK_BYTE> 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)(&hSenderPublic); // дескриптор открытого ключа ОтправителяckUnwrapMech.ulParameterLen = sizeof(CK_OBJECT_HANDLE);// класс объекта - секретный ключCK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;// шаблон импортируемого ключаCK_ATTRIBUTE unwrappedKeyTemplate[] = { {CKA_CLASS, &keyClass, sizeof(keyClass)}, {CKA_KEY_TYPE, &ckKeyType, sizeof(ckKeyType)}, {CKA_TOKEN, &s_TrueValue, sizeof(s_TrueValue)}, {CKA_PRIVATE, &s_TrueValue, sizeof(s_TrueValue)}, {CKA_EXTRACTABLE, &s_TrueValue, sizeof(s_TrueValue)}, {CKA_SENSITIVE, &s_FalseValue, sizeof(s_FalseValue)},};// дескриптор виртуального ключаhVirtualSecretKey = CK_INVALID_HANDLE;// производим импорт ключа на закрытом ключа ПолучателяASSERT_EQ(CKR_OK, Functions()->C_UnwrapKey(hSession, &ckUnwrapMech, hReceiverPrivate, wrappedKey.data(), wrappedKeySize, unwrappedKeyTemplate, ARRAYSIZE(unwrappedKeyTemplate), &hVirtualSecretKey));</pre><p><br /></p>Пример импорта ключа в память СКЗИ с использованием CKM_KUZNECHIK_KEXP_15_WRAP (только для версии 2.5.13 и выше):
<pre>// получаем дескрипторы приватного ключа Отправителя и публичного ключа ПолучателяCK_OBJECT_HANDLE hReceiverPublicKey = … ;CK_OBJECT_HANDLE hSenderPrivateKey = … ;// Транспортное представление ключа Кузнечикstd::vector<CK_BYTE> 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)(&hSenderPublic); // дескриптор открытого ключа ОтправителяckUnwrapMech.ulParameterLen = sizeof(CK_OBJECT_HANDLE);// класс объекта - секретный ключCK_OBJECT_CLASS keyClass = CKO_SECRET_KEY;// шаблон импортируемого ключаCK_ATTRIBUTE unwrappedKeyTemplate[] = { {CKA_CLASS, &keyClass, sizeof(keyClass)}, {CKA_KEY_TYPE, &ckKeyType, sizeof(ckKeyType)}, {CKA_TOKEN, &s_TrueValue, sizeof(s_TrueValue)}, {CKA_PRIVATE, &s_TrueValue, sizeof(s_TrueValue)}, {CKA_EXTRACTABLE, &s_TrueValue, sizeof(s_TrueValue)}, {CKA_SENSITIVE, &s_FalseValue, sizeof(s_FalseValue)},};// дескриптор виртуального ключаhVirtualSecretKey = CK_INVALID_HANDLE;// производим импорт ключа на закрытом ключа ПолучателяASSERT_EQ(CKR_OK, Functions()->C_UnwrapKey(hSession, &ckUnwrapMech, hReceiverPrivate, wrappedKey.data(), wrappedKeySize, unwrappedKeyTemplate, ARRAYSIZE(unwrappedKeyTemplate), &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_DERIVECKM_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, &deriveParams, sizeof(deriveParams) };// шаблон вырабатываемого ключаCK_ATTRIBUTE derivedKeyTemplate[] = { {CKA_CLASS, &keyClass, sizeof(keyClass)}, {CKA_KEY_TYPE, &keyTypeD, sizeof(keyType)}, {CKA_TOKEN, &bFalse, sizeof(bFalse)}, {CKA_PRIVATE, &bTrue, sizeof(bTrue)}, {CKA_EXTRACTABLE, &bTrue, sizeof(bTrue)}, {CKA_SENSITIVE, &bFalse, sizeof(bFalse)}, };// ...// получение дескриптора сессии// аутентификации Пользователем// получение дескриптора keyHandle ключа, на котором предполагается производить выработку// ...C_DeriveKey(hSession, &deriveMechanism, keyHandle, derivedKeyTemplate, sizeof(derivedKeyTemplate) / sizeof(CK_ATTRIBUTE), &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, &secretKeyClass, sizeof(secretKeyClass)}, // Класс - секретный ключ {CKA_TOKEN, &s_FalseValue, sizeof(s_FalseValue)}, // Ключ является объектом сессии {CKA_KEY_TYPE, &keyType, sizeof(keyType)}, // Тип ключа - двойственный ключ Магма {CKA_ENCRYPT,&s_TrueValue, sizeof(s_TrueValue)}, // На ключе можно шифровать {CKA_DECRYPT, &s_TrueValue, sizeof(s_TrueValue)} // На ключе можно расшифровывать }; // дескриптор вырабатываемого ключа CK_OBJECT_HANDLE hDerivedKey = CK_INVALID_HANDLE; // параметры механизма CK_ECDH1_DERIVE_PARAMS keg256DeriveParams; // механизм выработки ключа CK_MECHANISM gostKegDerifivationMech = { CKM_GOST_KEG, &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)&ukm[0]; keg256DeriveParams.ulPublicDataLen = ulPublicDataLen; keg256DeriveParams.pPublicData = pPublicData; // производим выработку ключа согласования C_DeriveKey(hSession, &gostKegDerifivationMech, senderPrivateKey, derivedKeyTemplate, sizeof(derivedKeyTemplate) / sizeof(CK_ATTRIBUTE), &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#11CK_OBJECT_HANDLE hDerivedKey;// ...// генерация ключевой пары Отправителя// получение дескриптора открытого ключа Получателя// ...// параметры для создания ключа согласованияJC_KT2_GOSTR3410_DERIVE_PARAMS jcCT2DeriveParams;jcCT2DeriveParams.kdf = kdf;jcCT2DeriveParams.hPublicKey = hPublicKey;jcCT2DeriveParams.pUKM = CK_BYTE_PTR(&ukm[0]);jcCT2DeriveParams.ulUKMLen = 8;CK_MECHANISM ckDeriveMechanism = {CKM_GOSTR3410_DERIVE, &jcCT2DeriveParams, sizeof(jcCT2DeriveParams)};// шаблон ключа согласованияCK_ULONG secretKeyClass = CKO_SECRET_KEY;CK_KEY_TYPE keyType = CKK_GOST28147;CK_ATTRIBUTE derivedKeyTemplate[] = { {CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass)}, {CKA_TOKEN, &bFalse, sizeof(bFalse)}, {CKA_GOST28147_PARAMS, id_Gost28147_89_CryptoPro_A_ParamSet, sizeof(id_Gost28147_89_CryptoPro_A_ParamSet)}, {CKA_KEY_TYPE, &keyType, sizeof(keyType)}, {CKA_WRAP, &bTrue, sizeof(bTrue)}, {CKA_UNWRAP, &bTrue, sizeof(bTrue)}};rv = C_DeriveKey(pkcs11SessionHandle, &ckDeriveMechanism, hPrivateKey, derivedKeyTemplate, sizeof(derivedKeyTemplate)/sizeof(CK_ATTRIBUTE), &hDerivedKey);if(rv != CKR_OK){ PrintError("C_DeriveKey", 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-2012CK_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#11CK_OBJECT_HANDLE hDerivedKey;// ...// генерация ключевой пары Отправителя// ...// параметры для создания ключа согласования// представлены в соответствии с рекомендациями ТК26uint32_t tc26DeriveParams[21] = {0};tc26DeriveParams[0] = kdf;tc26DeriveParams[1] = sizeof(publicKeyValue);memcpy(tc26DeriveParams + 2, &publicKeyValue[0], sizeof(publicKeyValue));tc26DeriveParams[18] = 8;memcpy(tc26DeriveParams + 19, &ukm[0], 8);CK_MECHANISM deriveMechanism = {CKM_GOSTR3410_2012_DERIVE, &tc26DeriveParams, sizeof(tc26DeriveParams)};// шаблон ключа согласованияCK_ULONG secretKeyClass = CKO_SECRET_KEY;CK_KEY_TYPE keyType = CKK_GOST28147;CK_ATTRIBUTE derivedKeyTemplate[] = { {CKA_CLASS, &secretKeyClass, sizeof(secretKeyClass)}, {CKA_TOKEN, &bFalse, sizeof(bFalse)}, {CKA_GOST28147_PARAMS, id_Gost28147_89_CryptoPro_A_ParamSet, sizeof(id_Gost28147_89_CryptoPro_A_ParamSet)}, {CKA_KEY_TYPE, &keyType, sizeof(keyType)}, {CKA_WRAP, &bTrue, sizeof(bTrue)}, {CKA_UNWRAP, &bTrue, sizeof(bTrue)}};rv = C_DeriveKey(pkcs11SessionHandle, &ckDeriveMechanism, hPrivateKey, derivedKeyTemplate, sizeof(derivedKeyTemplate)/sizeof(CK_ATTRIBUTE), &hDerivedKey);if(rv != CKR_OK){ PrintError("C_DeriveKey", rv); return;}</pre>