...
Подпись на Рутокен PINPad совместным механизмом хеширования и подписи
При использовании совместного механизма хеширования и подписи в функцию C_Sign()
с совместным механизмом (например, CKM_GOSTR3410_WITH_GOSTR3411
) передается текст в специальным формате для отображения его на экране Рутокен PINPad.
При вызове функции C_Sign()
на экране Рутокен PINPad появится текст сообщения, а функция будет ожидать нажатия пользователем кнопки подтверждения или отказа от операции на экране Рутокен PINPad.
Если пользователь подтверждает выполнение операции, то сообщение сначала хешируется внутри Рутокен PINPad, а затем подписывается. Функция C_Sign()
возвращает управление и 64-байтовый блок сформированной цифровой подписи .
Если пользователь отклоняет операцию подписи, функция C_Sign()
немедленно возвращает управление и код ошибки. Никаких вычислений хеша или цифровой подписи не производится.
Подпись на Рутокен PINPad отдельными механизмами хеширования и подписи
При использовании отдельных механизмов хеширования и подписи сначала в функцию C_Digest()
с механизмом хеширования (например, CKM_GOSTR3411
) передается текст в специальном формате для отображения его на экране Рутокен PINPad.
При вызове функция C_Digest()
вычисляет хеш и возвращает управление вместе с значением хеша. Исходное сообщение и значение хеша запоминаются внутри Рутокен PINPad.
Затем вызывается функция C_Sign()
с механизмом подписи (например, CKM_GOSTR3410
) и произвольным значением хеша. Рутокен PINPad подставляет сохраненное значение хеша вместо переданного функцией C_Sign()
значения и отображает на экране текст исходного сообщения. Функция C_Sign()
ожидает нажатия пользователем кнопки подтверждения или отказа от операции на экране Рутокен PINPad.
Если пользователь подтверждает выполнение операции, то сохраненное значение хеша в Рутокен PINPad подписывается, и функция C_Sign()
возвращает управление и 64-байтовый блок сформированной цифровой подписи.
Если пользователь отклоняет операцию подписи, функция C_Sign()
немедленно возвращает управление и код ошибки. Вычисления цифровой подписи не производится.
Пример подписи данных по алгоритму ГОСТ Р 34.10-2001
...
Далее шифрование можно выполнить для всего блока данных целиком, вызвав функцию C_Encrypt()
, или по частям, вызывая C_EncryptUpdate()
для каждого непоследнего блока и C_EncryptFinal()
для завершающего блока. Если в C_EncryptFinal()
передать пустой блок данных, то функция вернет суммарный размер всех блоков зашифрованных данных.
Пример шифрования данных по алгоритму ГОСТ 28147-89
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); 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; } |
...
Далее расшифрование выполняется вызовом функции C_Decrypt()
с передачей в нее зашифрованные данные. Размер расшифрованных данных можно узнать, вызвав C_Decrypt()
с пустым указателем вместо указателя на буфера для расшифрованных данных.
Примеры расшифрования данных по алгоритму ГОСТ 28147-89
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); 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; } |