...
Code Block | ||||
---|---|---|---|---|
| ||||
/* Размер синхропосылки в байтах */
#define UKM_KEG_LENGTH 24
CK_UTF8CHAR derivedKuznechikTwinKeyLabel[] = { "Derived Kuznechik twin key" };
CK_UTF8CHAR derivedMagmaTwinKeyLabel[] = { "Derived Magma twin key" };
CK_OBJECT_CLASS secretKeyObject = CKO_SECRET_KEY;
CK_KEY_TYPE keyTypeKuznechikTwin = CKK_KUZNECHIK_TWIN_KEY;
CK_KEY_TYPE keyTypeMagmaTwin = CKK_MAGMA_TWIN_KEY;
CK_BBOOL attributeTrue = CK_TRUE;
CK_BBOOL attributeFalse = CK_FALSE;
/* Значение открытого ключа получателя */
CK_BYTE cbPubRecipientKey[] = { 0xFF, 0x8D, 0xAB, 0x7F, 0x1C, 0x0B, 0x74, 0xA5, 0xAD, 0x7F, 0x0B, 0x5F, 0x8D, 0x5B, 0x3C, 0x44,
0x58, 0x37, 0x98, 0xC9, 0x25, 0x86, 0x40, 0x7E, 0xEC, 0x6E, 0xAF, 0x00, 0xCB, 0x44, 0x65, 0xA5,
0x22, 0x9A, 0x53, 0x56, 0x32, 0x97, 0x35, 0x80, 0x99, 0xCA, 0x1E, 0x17, 0x21, 0x3A, 0x96, 0x0E,
0x21, 0xFB, 0xC6, 0x0F, 0x25, 0x5B, 0x5D, 0x99, 0x4E, 0xC4, 0x5C, 0x42, 0x08, 0x7D, 0x06, 0x04 };
/*************************************************************************
* Шаблон для создания двойственного ключа экспорта типа Кузнечик *
*************************************************************************/
CK_ATTRIBUTE derivedTwinKeyTemplate[] =
{
{ CKA_LABEL, &derivedKuznechikTwinKeyLabel, sizeof(derivedKuznechikTwinKeyLabel) - 1}, // Метка ключа
{ CKA_CLASS, &secretKeyObject, sizeof(secretKeyObject) }, // Класс - секретный ключ
{ CKA_KEY_TYPE, &keyTypeKuznechikTwin, sizeof(keyTypeKuznechikTwin)}, // Тип ключа - двойственный Кузнечик
{ CKA_TOKEN, &attributeFalse, sizeof(attributeFalse)}, // Ключ является объектом сессии
{ CKA_MODIFIABLE, &attributeTrue, sizeof(attributeTrue)}, // Ключ может быть изменен после создания
{ CKA_PRIVATE, &attributeTrue, sizeof(attributeTrue)}, // Ключ доступен только после аутентификации на токене
{ CKA_EXTRACTABLE, &attributeTrue, sizeof(attributeTrue)}, // Ключ может быть извлечен в зашифрованном виде
{ CKA_SENSITIVE, &attributeFalse, sizeof(attributeFalse)} // Ключ может быть извлечен в открытом виде
};
/*************************************************************************
* Шаблон для создания двойственного ключа экспорта типа Магма *
*************************************************************************/
//CK_ATTRIBUTE derivedTwinKeyTemplate[] =
//{
// { CKA_LABEL, &derivedMagmaTwinKeyLabel, sizeof(derivedMagmaTwinKeyLabel) - 1}, // Метка ключа
// { CKA_CLASS, &secretKeyObject, sizeof(secretKeyObject) }, // Класс - секретный ключ
// { CKA_KEY_TYPE, &keyTypeMagmaTwin, sizeof(keyTypeMagmaTwin)}, // Тип ключа - двойственный Магма
// { CKA_TOKEN, &attributeFalse, sizeof(attributeFalse)}, // Ключ является объектом сессии
// { CKA_MODIFIABLE, &attributeTrue, sizeof(attributeTrue)}, // Ключ может быть изменен после создания
// { CKA_PRIVATE, &attributeTrue, sizeof(attributeTrue)}, // Ключ доступен только после аутентификации на токене
// { CKA_EXTRACTABLE, &attributeTrue, sizeof(attributeTrue)}, // Ключ может быть извлечен в зашифрованном виде
// { CKA_SENSITIVE, &attributeFalse, sizeof(attributeFalse)} // Ключ может быть извлечен в открытом виде
//};
CK_MECHANISM gostKegDerifivationMech = { CKM_VENDOR_GOST_KEG, NULL_PTR, 0 };
CK_VENDOR_GOST_KEG_PARAMS keg256DeriveParams;
CK_ATTRIBUTE attrDerivedKeyValue = { CKA_VALUE, NULL_PTR, 0 }; // Структура данных типа CK_ATTRIBUTE для хранения значения атрибута CKA_VALUE
CK_BYTE ukm[UKM_KEG_LENGTH]; // Буфер, содержащий UKM
CK_OBJECT_HANDLE hDerivedKey = NULL_PTR; // Хэндл выработанного общего ключа
CK_OBJECT_HANDLE hObject; // Хэндл объекта
...
/*************************************************************************
* Установить параметры в структуре типа CK_VENDOR_GOST_KEG_PARAMS *
* для выработки двлйственного ключа *
*************************************************************************/
rv = pFunctionList->C_GenerateRandom(hSession, ukm, sizeof(ukm));
if (rv != CKR_OK)
{
printf(" -> Failed\n");
goto exit;
}
/*************************************************************************
* Поместить в структуру типа CK_MECHANISM параметры, необходимые *
* для выработки ключа обмена *
*************************************************************************/
keg256DeriveParams.pPublicData = cbPubRecipientKey;
keg256DeriveParams.ulPublicDataLen = sizeof(cbPubRecipientKey);
keg256DeriveParams.pUKM = ukm;
keg256DeriveParams.ulUKMLen = sizeof(ukm);
gostR3410_12DerivationMech.pParameter = &keg256DeriveParams;
gostR3410_12DerivationMech.ulParameterLen = sizeof(keg256DeriveParams);
/* Выработать общий двойственный ключ на основании закрытого ключа отправителя и открытого ключа получателя */
printf("C_DeriveKey");
rv = pFunctionList->C_DeriveKey(hSession, // Хэндл открытой с правами Пользователя сессии
&gostR3410_12DerivationMech, // Механизм ключевого обмена
hPrivateKey, // Хэндл закрытого ключа отправителя
derivedTwinKeyTemplate, // Шаблон создания общего ключа
arraysize(derivedTwinKeyTemplate), // Размер шаблона
&hDerivedKey); // Хэндл общего выработанного ключа
if (rv != CKR_OK)
{
printf(" -> Failed\n");
goto exit;
}
printf(" -> OK\n");
/* Получить размер буфера для хранения значения атрибута CKA_VALUE*/
printf("Getting object value size");
rv = pFunctionList->C_GetAttributeValue(hSession, // Хэндл открытой с правами Пользователя сессии
hDerivedKey, // Хэндл общего ключа
&attrDerivedKeyValue, // Шаблон получения значения атрибута
1); // Количество атрибутов в шаблоне
if (rv != CKR_OK)
{
printf(" -> Failed\n");
goto exit;
}
printf(" -> OK\n");
/* Выделить необходимое количество памяти для значения атрибута */
attrDerivedKeyValue.pValue = (CK_BYTE*)malloc(attrDerivedKeyValue.ulValueLen);
if (attrDerivedKeyValue.pValue == NULL)
{
printf("Memory allocation for attrDerivedKeyValue failed! \n");
goto exit;
}
memset(attrDerivedKeyValue.pValue,
0,
(attrDerivedKeyValue.ulValueLen * sizeof(CK_BYTE)));
/* Получить значение общего двойственного ключа */
printf("Getting object value");
rv = pFunctionList->C_GetAttributeValue(hSession, // Хэндл открытой с правами Пользователя сессии
hDerivedKey, // Хэндл общего ключа
&attrDerivedKeyValue, // Шаблон получения значения атрибута
1); // Количество атрибутов в шаблоне
if (rv != CKR_OK)
{
printf(" -> Failed\n");
goto exit;
}
printf(" -> OK\n");
/* Распечатать буфер со значением общего двойственного ключа */
printf("Derived key data is:\n");
for (size_t i = 0; i < attrDerivedKeyValue.ulValueLen; i++)
{
printf("%02X ", ((CK_BYTE_PTR)attrDerivedKeyValue.pValue)[i]);
if ((i + 1) % 8 == 0)
printf("\n");
}
exit:
if (attrDerivedKeyValue.pValue)
{
free(attrDerivedKeyValue.pValue);
attrDerivedKeyValue.pValue = NULL_PTR;
attrDerivedKeyValue.ulValueLen = 0;
}
if (rv != CKR_OK)
{
pFunctionList->C_DestroyObject(hSession,
hDerivedKey);
hDerivedKey = NULL_PTR;
}
if (rv != CKR_OK)
printf("\nDeriving failed!\n\n");
else
printf("Deriving has been completed successfully.\n\n"); |
...
Подпись данных отдельными механизмами хеширования и подписи
...
Пример подписи данных по алгоритму ГОСТ Р 34.10-2012 отдельными механизмами хеширования и подписи для всех устройств Рутокен
...
При использовании совместного механизма и хеширование, и подпись выполняются функцией C_Sign()
. Сначала в функцию C_SignInit()
передается совместный механизм (например, CKM_GOSTR3410_WITH_GOSTR3411
), а затем в функцию C_Sign()
– сообщение.
Пример подписи данных по алгоритму ГОСТ Р 34.10-2012 совместным механизмом хеширования и подписи
...
Пример подписи данных по алгоритму ECDSA отдельными механизмами хеширования и подписи
...