...
Code Block | ||||
---|---|---|---|---|
| ||||
CK_SLOT_ID_PTR aSlots = NULL_PTR; // Указатель на массив идентификаторов слотов CK_ULONG ulSlotCount = 0; // Количество идентификаторов слотов в массиве while(TRUE) { ... /* Получить количество слотов c подключенными токенами */ printf(" Getting number of connected slots"); rv = pFunctionList->C_GetSlotList(CK_TRUE, NULL_PTR, &ulSlotCount); if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); aSlots = (CK_SLOT_ID*)malloc(ulSlotCount * sizeof(CK_SLOT_ID)); if (aSlots == NULL) { printf("Memory allocation for aSlots failed! \n"); break; } memset(aSlots, 0, (ulSlotCount * sizeof(CK_SLOT_ID))); /* Получить список слотов c подключенными токенами */ printf(" Getting list of connected slots"); rv = pFunctionList->C_GetSlotList(CK_TRUE, aSlots, &ulSlotCount); if (rv != CKR_OK) { printf(" -> Failed %X\n", (int)rv); break; } printf(" -> OK\n"); printf(" Slots available: 0x%8.8X\n", (int)ulSlotCount); ... break; } if (aSlots) { free(aSlots); aSlots = NULL_PTR; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
CK_C_EX_GetFunctionListExtended pfGetFunctionListEx = NULL_PTR; // Указатель на функцию C_EX_GetFunctionListExtended CK_FUNCTION_LIST_EXTENDED_PTR pFunctionListEx = NULL_PTR; // Указатель на список функций расширения PKCS#11, хранящийся в структуре CK_FUNCTION_LIST_EXTENDED CK_TOKEN_INFO_EXTENDED tokenInfoEx; // Структура данных типа CK_TOKEN_INFO_EXTENDED с информацией о токене while(TRUE) { ... printf("Determining token type"); /* Получить адрес функции запроса структуры с указателями на функции расширения */ pfGetFunctionListEx = (CK_C_EX_GetFunctionListExtended)GetProcAddress(hModule, "C_EX_GetFunctionListExtended"); if (pfGetFunctionListEx == NULL_PTR) { printf(" -> Failed\n"); break; } /* Получить структуру с указателями на функции расширения */ rv = pfGetFunctionListEx(&pFunctionListEx); if (rv != CKR_OK) { printf(" -> Failed\n"); break; } memset(&tokenInfoEx, 0, sizeof(CK_TOKEN_INFO_EXTENDED)); tokenInfoEx.ulSizeofThisStructure = sizeof(CK_TOKEN_INFO_EXTENDED); /* Получить расширенную информацию о подключенном токене */ rv = pFunctionListEx->C_EX_GetTokenInfoExtended(aSlots[0], // Идентификатор слота, к которому подключен токен &tokenInfoEx); // Буфер для помещения информации о токене if (rv != CKR_OK) { printf(" -> Failed\n"); break; } /* Определить класс токена */ ifswitch (tokenInfoEx.ulTokenClass == TOKEN_CLASS_S) { bIsRutokenPINPad = FALSE; case TOKEN_CLASS_S: printf(": Rutoken / Rutoken S\n"); } else if (tokenInfoEx.ulTokenClass == case TOKEN_CLASS_ECP): { bIsRutokenPINPad = FALSE; printf(": Rutoken ECP\n"); } else if (tokenInfoEx.ulTokenClass == case TOKEN_CLASS_LITE): { bIsRutokenPINPad = FALSE; printf(": Rutoken Lite\n"); } else if (tokenInfoEx.ulTokenClass ==case TOKEN_CLASS_WEB): { bIsRutokenPINPad = FALSE; printf(": printf(": Rutoken WEB\n"); } else if (tokenInfoEx.ulTokenClass == case TOKEN_TYPE_RUTOKEN_PINPAD_FAMILY): { bIsRutokenPINPad = TRUE; printf(": Rutoken PINPad\n"); } else { bIsRutokenPINPad = FALSE; default: printf(": undefined\n"); } break; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
/* Данные для хеширования в виде двоичной строки */ CK_BYTE pbtData[] = { 0x3C, 0x21, 0x50, 0x49, 0x4E, 0x50, 0x41, 0x44, 0x46, 0x49, 0x4C, 0x45, 0x20, 0x52, 0x55, 0x3E, 0x3C, 0x21, 0x3E, 0xED, 0xE5, 0xE2, 0xE8, 0xE4, 0xE8, 0xEC, 0xFB, 0xE9, 0x20, 0xF2, 0xE5, 0xEA }; /* Механизм хеширования ГОСТ Р 34.11-94 */ CK_MECHANISM HashMech = {CKM_GOSTR3411, NULL_PTR, 0}; CK_BYTE_PTR pbtHash = NULL_PTR; // Указатель на буфер для значения хеша данных CK_ULONG ulHashSize = 0; // Размер буфера в байтах while(TRUE) { ... /* Инициализировать операцию хеширования */ printf("C_DigestInit"); rv = pFunctionList->C_DigestInit(hSession, // Хэндл сессии &HashMech); // Механизм хеширования if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Определить размер значения хеша данных */ printf("C_Digest step 1"); rv = pFunctionList->C_Digest( hSession, // Хэндл сессии pbtData, // Буфер с данными для хеширования arraysize(pbtData), // Размер данных для хеширования pbtHash, // Буфер для вычисленного значения хеша &ulHashSize); // Размер значения хеша if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); pbtHash = (CK_BYTE*)malloc(ulHashSize); if (pbtHash == NULL) { printf("Memory allocation for pbtHash failed! \n"); break; } memset(pbtHash, 0, (ulHashSize * sizeof(CK_BYTE))); /* Сформировать хеш от исходных данных */ printf("C_Digest step 2"); rv = pFunctionList->C_Digest(hSession, // Хэндл сессии pbtData, // Буфер с данными для хеширования arraysize(pbtData), // Размер данных для хеширования pbtHash, // Буфер для вычисленного значения хеша &ulHashSize); // Размер значения хеша if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); break; } |
...
Подпись на Рутокен PINPad совместным механизмом хеширования и подписи
При использовании совместного механизма хеширования и подписи в функцию C_Sign()
с совместным механизмом (например, CKM_GOSTR3410_WITH_GOSTR3411
) передается текст в специальным формате для отображения его на экране Рутокен PINPad.
При вызове функции C_Sign()
на экране Рутокен PINPad появится текст сообщения, а функция будет ожидать нажатия пользователем кнопки подтверждения или отказа от операции на экране Рутокен PINPad.
Если пользователь подтверждает выполнение операции, то сообщение сначала хешируется внутри Рутокен PINPad, а затем подписывается. Функция C_Sign()
возвращает управление и 64-байтовый блок сформированной цифровой подписи размером 64 байта для механизмов CKM_GOSTR3410_WITH_GOSTR3411
и CKM_GOSTR3410_WITH_GOSTR3411_12_256
и
128 байтдля механизма
CKM_GOSTR3410_WITH_GOSTR3411_12_512
.
Если пользователь отклоняет операцию подписи, функция C_Sign()
немедленно возвращает управление и код ошибки. Никаких вычислений хеша или цифровой подписи не производится.
Подпись на Рутокен PINPad отдельными механизмами хеширования и подписи
При использовании отдельных механизмов хеширования и подписи сначала в функцию C_Digest()
с механизмом хеширования (например, CKM_GOSTR3411
) передается текст в специальном формате для отображения его на экране Рутокен PINPad.
При вызове функция C_Digest()
вычисляет хеш и возвращает управление вместе с значением хеша. Исходное сообщение и значение хеша запоминаются внутри Рутокен PINPad.
Затем вызывается функция C_Sign()
с механизмом подписи (например, CKM_GOSTR3410
) и произвольным значением хеша. Рутокен PINPad подставляет сохраненное значение хеша вместо переданного Рутокен PINPad сверяет сохраненное значение хеша с переданным функцией C_Sign()
значения и в случае совпадения отображает на экране текст исходного сообщения. Функция C_Sign()
ожидает нажатия пользователем кнопки подтверждения или отказа от операции на экране Рутокен PINPad. Если значения не совпадают, функция C_Sign()
возвращает ошибку без вывода на экране текста сообщения.
Если пользователь подтверждает выполнение операции, то сохраненное значение хеша в Рутокен PINPad подписывается, и функция C_Sign()
возвращает управление и 64-байтовый блок сформированной цифровой подписи размером 64 байта для механизма CKM_GOSTR3410
и 128 байт для механизма CKM_GOSTR3410_512
.
Если пользователь отклоняет операцию подписи, функция C_Sign()
немедленно возвращает управление и код ошибки. Вычисления цифровой подписи не производится.
Пример подписи данных по алгоритму ГОСТ Р 34.10-2001
Code Block | ||||
---|---|---|---|---|
| ||||
/* Механизм подписи/проверки подписи по алгоритму ГОСТ Р 34.10-2001 */ CK_MECHANISM SigVerMech = {CKM_GOSTR3410, NULL_PTR, 0}; /* Набор параметров КриптоПро алгоритма ГОСТ Р 34.11-1994 */ CK_BYTE GOST3411params[] = { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01 }; /* Механизм подписи/проверки подписи по алгоритму ГОСТ Р 34.10-2001 с хешированием по алгоритму ГОСТ Р 34.11-94*/ CK_MECHANISM HashSigVerMech = {CKM_GOSTR3410_WITH_GOSTR3411, GOST3411params, sizeof(GOST3411params)}; CK_BYTE_PTR pbtSignature = NULL_PTR; // Указатель на буфер, содержащий подпись для исходных данных CK_ULONG ulSignatureSize = 0; // Размер буфера, содержащего подпись для исходных данных, в байтах while(TRUE) { ... /* Инициализировать операцию подписи данных */ printf("C_SignInit"); rv = pFunctionList->C_SignInit( hSession, // Хэндл сессии &SigVerMech, // Механизм подписи hPrivateKey ); // Хэндл закрытого ключа if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Определить размер подписи*/ printf("C_Sign step 1"); rv = pFunctionList->C_Sign( hSession, // Хэндл сессии pbtHash, // Буфер с данными для подписи ulHashSize, // Длина подписываемых данных pbtSignature, // Буфер с подписью &ulSignatureSize); // Длина подписи if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); pbtSignature = (CK_BYTE*)malloc(ulSignatureSize);\n"); pbtSignature = (CK_BYTE*)malloc(ulSignatureSize); if (pbtSignature == NULL) { printf("Memory allocation for pbtSignature failed! \n"); break; } memset( pbtSignature, 0, ulSignatureSize * sizeof(CK_BYTE)); /* Подписать исходные данные */ printf("C_Sign step 2"); rv = pFunctionList->C_Sign( hSession, // Хэндл сессии pbHash, // Буфер с данными для подписи ulHashSize, // Длина подписываемых данных pbtSignature, // Буфер с подписью &ulSignatureSize); // Длина подписи if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Распечатать буфер, содержащий подпись */ printf("Signature buffer is: \n"); for (i = 0; i < ulSignatureSize; i++) { printf("%02X ", pbtSignature[i]); if ((i + 1) % 8 == 0) printf("\n"); } break; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
/* Сформированный запрос на сертификат в виде двоичной строки */ CK_BYTE pbtReqCert[] = {0x30, 0x82, 0x02, 0x69, 0x02, 0x01, 0x00, 0x30, 0x82, 0x01, 0x83, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x52, 0x55, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 0x06, 0x4d, 0x6f, 0x73, 0x63, 0x6f, 0x77, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x03, 0x6d, 0x73, 0x6b, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x09, 0x13, 0x06, 0x73, 0x74, 0x72, 0x65, 0x65, 0x74, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x05, 0x41, 0x6b, 0x74, 0x69, 0x76, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x02, 0x49, 0x54, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x10, 0x13, 0x0e, 0x70, 0x6f, 0x73, 0x74, 0x61, 0x6c, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x31, 0x1b, 0x30, 0x19, 0x06, 0x03, 0x55, 0x04, 0x0c, 0x1e, 0x12, 0x04, 0x34, 0x04, 0x3e, 0x04, 0x3b, 0x04, 0x36, 0x04, 0x3d, 0x04, 0x3e, 0x04, 0x41, 0x04, 0x42, 0x04, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x08, 0x2a, 0x85, 0x03, 0x03, 0x81, 0x03, 0x01, 0x01, 0x12, 0x0b, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x38, 0x37, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x2a, 0x85, 0x03, 0x64, 0x03, 0x12, 0x0b, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x38, 0x37, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x2a, 0x85, 0x03, 0x64, 0x01, 0x12, 0x0b, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x38, 0x37, 0x31, 0x16, 0x30, 0x14, 0x06, 0x05, 0x2a, 0x85, 0x03, 0x64, 0x05, 0x12, 0x0b, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x38, 0x37, 0x31, 0x2f, 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x1e, 0x26, 0x04, 0x24, 0x04, 0x30, 0x04, 0x3c, 0x04, 0x38, 0x04, 0x3b, 0x04, 0x38, 0x04, 0x4f, 0x00, 0x20, 0x04, 0x18, 0x04, 0x3c, 0x04, 0x4f, 0x00, 0x20, 0x04, 0x1e, 0x04, 0x47, 0x04, 0x35, 0x04, 0x41, 0x04, 0x42, 0x04, 0x32, 0x04, 0x3e, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x41, 0x13, 0x09, 0x70, 0x73, 0x65, 0x75, 0x64, 0x6f, 0x6e, 0x79, 0x6d, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x04, 0x13, 0x07, 0x73, 0x75, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x2a, 0x13, 0x0a, 0x67, 0x69, 0x76, 0x65, 0x6e, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x31, 0x22, 0x30, 0x20, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x13, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x40, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40, 0x26, 0x68, 0x22, 0x87, 0x6b, 0x3e, 0x60, 0xde, 0x6e, 0xcf, 0x7d, 0x9b, 0xc5, 0x99, 0x49, 0x88, 0xe3, 0xce, 0x8d, 0x05, 0xb2, 0x0a, 0x3c, 0x3d, 0x2c, 0xb3, 0x7c, 0xc6, 0x9e, 0x7e, 0x5a, 0xc6, 0x95, 0xde, 0x97, 0x86, 0x9a, 0x56, 0xe3, 0xc5, 0xf5, 0xc5, 0xca, 0x9a, 0x4a, 0xd9, 0x11, 0xa0, 0x40, 0x08, 0xca, 0x70, 0x29, 0x13, 0x64, 0x7f, 0xa1, 0x6c, 0x5b, 0x5b, 0x25, 0xc9, 0xa6, 0x0c, 0xa0, 0x78, 0x30, 0x76, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0e, 0x31, 0x69, 0x30, 0x67, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x06, 0xc0, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x20, 0x04, 0x0c, 0x30, 0x0a, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, 0x03, 0x64, 0x71, 0x01, 0x30, 0x2b, 0x06, 0x05, 0x2a, 0x85, 0x03, 0x64, 0x6f, 0x04, 0x22, 0x0c, 0x20, 0xd0, 0xa1, 0xd0, 0x9a, 0xd0, 0x97, 0xd0, 0x98, 0x20, 0x22, 0xd0, 0xa0, 0xd0, 0xa3, 0xd0, 0xa2, 0xd0, 0x9e, 0xd0, 0x9a, 0xd0, 0x95, 0xd0, 0x9d, 0x20, 0xd0, 0xad, 0xd0, 0xa6, 0xd0, 0x9f, 0x22 }; /* Механизм хеширования ГОСТ Р 34.11-94 */ CK_MECHANISM HashMech = {CKM_GOSTR3411, NULL_PTR, 0}; /* Механизм подписи/проверки подписи по алгоритму ГОСТ Р 34.10-2001 */ CK_MECHANISM SigVerMech = {CKM_GOSTR3410, NULL_PTR, 0}; CK_BYTE_PTR pbtHash = NULL_PTR; // Указатель на буфер для значения хеша данных CK_ULONG ulHashSize = 0; // Размер буфера в байтах CK_BYTE_PTR pbtSignature = NULL_PTR; // Указатель на буфер, содержащий подпись для исходных данных CK_ULONG ulSignatureSize = 0; // Размер буфера, содержащего подпись для исходных данных, в байтах while(TRUE) { ... /* Инициализировать операцию хеширования */ printf("C_DigestInit"); rv = pFunctionList->C_DigestInit(hSession, // Хэндл сессии &HashMech); // Механизм хеширования if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Определить размер значения хеша данных */ printf("C_Digest step 1"); rv = pFunctionList->C_Digest( hSession, // Хэндл сессии pbtReqCert, // Буфер с запросом на сертификат arraysize(pbtReqCert), // Размер буфера с запросом на сертификат pbtHash, // Буфер для значения хеша &ulHashSize); // Размер значения хеша if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); pbtHash = (CK_BYTE*)malloc(ulHashSize); if (pbtHash == NULL) { printf("Memory allocation for pbtHash failed! \n"); break; } memset(pbtHash, 0, (ulHashSize * sizeof(CK_BYTE))); /* Сформировать хеш от исходных данных */ printf("C_Digest step 2"); rv = pFunctionList->C_Digest(hSession, // Хэндл сессии pbtReqCert, // Буфер с запросом на сертификат arraysize(pbtReqCert), // Размер буфера с запросом на сертификат pbtHash, // Буфер для значения хеша &ulHashSize); // Размер значения хеша if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Инициализировать операцию подписи данных */ printf("C_SignInit"); rv = pFunctionList->C_SignInit( hSession, // Хэндл сессии &SigVerMech, // Механизм подписи hPrivateKey ); // Хэндл закрытого ключа if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Определить размер подписи*/ printf("C_Sign step 1"); rv = pFunctionList->C_Sign( hSession, // Хэндл сессии pbtHash, // Буфер с данными для подписи ulHashSize, // Длина подписываемых данных pbtSignature, // Буфер с подписью &ulSignatureSize); // Длина подписи if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); pbtSignature = (CK_BYTE*)malloc(ulSignatureSize); if (pbtSignature == NULL) { printf("Memory allocation for pbtSignature failed! \n"); break; } memset( pbtSignature, 0, ulSignatureSize * sizeof(CK_BYTE)); /* Подписать исходные данные */ printf("C_Sign step 2"); rv = pFunctionList->C_Sign( hSession, // Хэндл сессии pbHash, // Буфер с данными для подписи ulHashSize, // Длина подписываемых данных pbtSignature, // Буфер с подписью &ulSignatureSize); // Длина подписи if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Распечатать буфер, содержащий подпись */ printf("Signature buffer is: \n"); for (i = 0; i < ulSignatureSize; i++) { printf("%02X ", pbtSignature[i]); if ((i + 1) % 8 == 0) printf("\n"); } break; } |
...
CKM_GOST28147_ECB
для шифрования алгоритмом ГОСТ 28147-89 в режиме простой замены,CKM_GOST28147
для шифрования алгоритмом ГОСТ 28147-89 в режиме гаммирования с обратной связью,CKM_RSA_PKCS
для шифрования алгоритмом RSAдля шифрования алгоритмом RSA.
Warning | ||
---|---|---|
| ||
Так как в режиме простой замены (механизм |
Шифрование данных
Для шифрования данных одним блоком служат функции C_EncryptInit()
и C_Encrypt()
, для поточного – С_EncryptInit(), C_EncryptUpdate()
и C_EncryptFinal().
...
Code Block | ||||
---|---|---|---|---|
| ||||
/* Данные для шифрования */ CK_BYTE pbtData[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00 }; /* Механизм шифрования/расшифрования по алгоритму ГОСТ 28147-89 в режиме простой замены */ CK_MECHANISM EncDecMech = {CKM_GOST28147_ECB, NULL_PTR, 0}; CK_BYTE_PTR pbtEncryptedData = NULL_PTR; // Указатель на буфер, содержащий зашифрованные данные CK_ULONG ulEncryptedDataSize = 0; // Размер буфера с зашифрованными данными, в байтах while(TRUE) { ... /* Инициализировать операцию шифрования */ printf("C_EncryptInit"); rv = pFunctionList->C_EncryptInit(hSession, // Хэндл сессии &EncDecMech, // Механизм шифрования hSecKey); // Хэндл секретного ключа if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Получить размер зашифрованного текста */ printf("Getting encrypted data size"); rv = pFunctionList->C_Encrypt(hSession, // Хэндл сессии pbtData, // Буфер с открытыми данными для шифрования arraysize(pbtData), // Длина буфера с открытыми данными, в байтах NULL, // Буфер с зашифрованными данными &ulEncryptedDataSize); // Длина буфера с зашифрованными данными if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); pbtEncryptedData = (CK_BYTE*)malloc(ulEncryptedDataSize); if (pbtEncryptedData == NULL) { printf("Memory allocation for pbtEncryptedData failed! \n"); break; } memset(pbtEncryptedData, 0, (ulEncryptedDataSize * sizeof(CK_BYTE))); /* Зашифровать открытый текст */ printf("C_Encrypt"); rv = pFunctionList->C_Encrypt(hSession, // Хэндл сессии pbtData, // Буфер с открытыми данными для шифрования arraysize(pbtData), // Длина буфера с открытыми данными, в байтах pbtEncryptedData, // Буфер с зашифрованными данными &ulEncryptedDataSize); // Длина буфера с зашифрованными данными if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); printf("Encrypted buffer is:\n"); for (i = 0; i < ulEncryptedDataSize; i++) { printf("%02X ", pbtEncryptedData[i]); if ((i + 1) % 8 == 0) printf("\n"); } break; } |
Code Block | ||||
---|---|---|---|---|
| ||||
/* Данные для шифрования */ CK_BYTE pbtData[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00 }; CK_BYTE IV[] = {1, 2, 3, 4, 5, 6, 7, 8}; // Значение вектора инициализации CK_ULONG ulIVLen = 8; // Длина вектора инициализации /* Механизм шифрования/расшифрования по алгоритму ГОСТ 28147-89 в режиме гаммирования с обратной связью */ CK_MECHANISM EncDecStreamMech = {CKM_GOST28147, IV, ulIVLen}; CK_BYTE_PTR pbtEncryptedData = NULL_PTR; // Указатель на буфер, содержащий зашифрованные данные CK_ULONG ulEncryptedDataSize = 0; // Размер буфера с зашифрованными данными, в байтах CK_ULONG ulBlockSize = 32; // Размер блока данных, в байтах CK_ULONG ulCurrentPosition = 0; // Текущее начало блока CK_ULONG ulRestLen = 0; // Размер оставшегося буфера, в байтах while(TRUE) { ... /* Инициализировать операцию шифрования */ printf("C_EncryptInit"); rv = pFunctionList->C_EncryptInit(hSession, // Хэндл сессии &EncDecStreamMech, // Механизм шифрования hSecKey); // Хэндл секретного ключа if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Зашифровать открытый текст */ ulEncryptedDataSize = arraysize(pbtData); ulRestLen = arraysize(pbtData); pbtEncryptedData = (CK_BYTE*)malloc(ulEncryptedDataSize); if (pbtEncryptedData == NULL) { printf("Memory allocation for pbtEncryptedData failed! \n"); break; } memset( pbtEncryptedData, 0, (ulEncryptedDataSize * sizeof(CK_BYTE))); while (ulRestLen) { if (ulBlockSize > ulRestLen) ulBlockSize = ulRestLen; printf("Block size: %u B (Total: %u of %u) ", ulBlockSize, ulCurrentPosition + ulBlockSize, ulEncryptedDataSize); rv = pFunctionList->C_EncryptUpdate(hSession, // Хэндл сессии pbtData + ulCurrentPosition, // Буфер с блоком данных для шифрования ulBlockSize, // Размер блока, в байтах pbtEncryptedData + ulCurrentPosition, // Буфер с блоком зашифрованных данных &ulBlockSize); // Размер блока, в байтах if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); ulCurrentPosition += ulBlockSize; ulRestLen -= ulBlockSize; } if (rv != CKR_OK) break; printf("Finalizing encryption"); rv = pFunctionList->C_EncryptFinal( hSession, // Хэндл сессии NULL_PTR, // Буфер с последним блоком данных &ulEncryptedDataSize); // Длина буфера if (rv != CKR_OK) { printf(" -> Failed\n"); break; } printf(" -> OK\n"); /* Распечатать буфер, содержащий зашифрованные данные*/ printf("Encrypted buffer is:\n"); for (i = 0; i < ulEncryptedDataSize; i++) { printf("%02X ", pbtEncryptedData[i]); if ((i + 1) % 8 == 0) printf("\n"); } break; } |
...
Code Block | ||||
---|---|---|---|---|
| ||||
while(TRUE)
{
...
/* Инициализировать операцию расшифрования */
printf("C_DecryptInit");
rv = pFunctionList->C_DecryptInit(hSession, // Хэндл сессии
&EncDecStreamMech, // Механизм расшифрования
hSecKey); // Хэндл секретного ключа
if (rv != CKR_OK)
{
printf(" -> Failed\n");
break;
}
printf(" -> OK\n");
/* Расшифровать шифротекст */
printf("Getting decrypted data size");
rv = pFunctionList->C_Decrypt(hSession, // Хэндл сессии
pbtEncryptedData, // Буфер с зашифрованными данными
ulEncryptedDataSize, // Размер зашифрованных данных
NULL_PTR, // Буфер с расшифрованными данными
&ulDecryptedDataSize); // Размер расшифрованных данных
if (rv != CKR_OK)
{
printf(" -> Failed\n");
break;
}
printf(" -> OK\n");
pbtDecryptedData = (CK_BYTE*)malloc(ulDecryptedDataSize);
if (pbtDecryptedData == NULL)
{
printf("Memory allocation for pbtDecryptedData failed! \n");
break;
}
memset(pbtDecryptedData,
0,
(ulDecryptedDataSize * sizeof(CK_BYTE)));
printf("C_Decrypt");
rv = pFunctionList->C_Decrypt(hSession, // Хэндл сессии
pbtEncryptedData, // Буфер с зашифрованными данными
ulEncryptedDataSize, // Размер зашифрованных данных
pbtDecryptedData, // Буфер с расшифрованными данными
&ulDecryptedDataSize); // Размер расшифрованных данных
if (rv != CKR_OK)
{
printf(" -> Failed\n");
break;
}
printf(" -> OK\n");
/* Распечатать буфер, содержащий расшифрованный текст */
printf("Decrypted buffer is:\n");
for (i = 0;
i < ulDecryptedDataSize;
i++)
{
printf("%02X ", pbtDecryptedData[i]);
if ((i + 1) % 8 == 0)
printf("\n");
}
break;
}
if (pbtEncryptedData)
{
free(pbtEncryptedData);
pbtEncryptedData = NULL_PTR;
}
if (pbtDecryptedData)
{
free(pbtDecryptedData);
pbtDecryptedData = NULL_PTR;
} |
...