Проблемы с работой примера хэширования из SDK/pkcs11/sample/standart
Здравствуйте. Не понимаю в чём проблема: запустил пример из SDK по созданию хэша с входными данными "Hello crypto world" с использованием алгоритма ГОСТ 2012-256. Должен получить следующее:
dd b5 1e 17 37 cc 3d 5f b0 64 e3 c2 a cc b5 1a 47 9c c7 72 30 55 ca 3a 21 8c 2d e4 46 7c a7 12. На деле имеем:
Решил проверить те же входные данные с алгоритмом SHA-1, т.к. результат работы можно легко получить на различных сайтах онлайн. На выходе получаю следующие данные:
Проверил на нескольких сайтах онлайн с этими же входными данными и получил совсем другой результат:
Как такое возможно? Использую Рутокен ЭЦП 2.0.
Код прикреплю на всякий случай:
/*************************************************************************
* Rutoken *
* Copyright (c) 2003-2019, CJSC Aktiv-Soft. All rights reserved. *
* Подробная информация: http://www.rutoken.ru *
*------------------------------------------------------------------------*
* Пример работы с Рутокен при помощи библиотеки PKCS#11 на языке C *
*------------------------------------------------------------------------*
* Использование команд вычисления хэш-кода: *
* - установление соединения с Рутокен в первом доступном слоте; *
* - определение типа подключенного токена; *
* - вычисление хэш-кода ГОСТ Р 34.11-2012(512); *
* - закрытие соединения с Рутокен. *
*------------------------------------------------------------------------*
* Данный пример является самодостаточным. *
*************************************************************************/
#include <Common.h>
/*************************************************************************
* Данные, от которых будет производиться вычисление хэш-кода *
*************************************************************************/
static CK_BYTE data[] = { "Hello crypto world" };
int main(void)
{
HMODULE module; // Хэндл загруженной библиотеки PKCS#11
CK_SESSION_HANDLE session; // Хэндл открытой сессии
CK_FUNCTION_LIST_PTR functionList; // Указатель на список функций PKCS#11, хранящийся в структуре CK_FUNCTION_LIST
CK_C_GetFunctionList getFunctionList; // Указатель на функцию C_GetFunctionList
CK_SLOT_ID_PTR slots; // Массив идентификаторов слотов
CK_ULONG slotCount; // Количество идентификаторов слотов в массиве
CK_MECHANISM_TYPE_PTR mechanisms; // Массив поддерживаемых механизмов
CK_ULONG mechanismCount; // Количество поддерживаемых механизмов
CK_BYTE_PTR hash; // Указатель на временный буфер для хэш-кода данных
CK_ULONG hashSize; // Размер временного буфера в байтах
CK_RV rv; // Код возврата. Могут быть возвращены только ошибки, определенные в PKCS#11
CK_ULONG i; // Вспомогательная переменная-счетчик в циклах
int isGostR3411_12_256Supported = 0; // Флаг для проверки поддержки токеном CKM_GOSTR3411_12_256
int errorCode = 1; // Флаг ошибки
/*************************************************************************
* Выполнить действия для начала работы с библиотекой PKCS#11 *
*************************************************************************/
printf("Initialization...\n");
/*************************************************************************
* Загрузить библиотеку *
*************************************************************************/
module = LoadLibrary(PKCS11ECP_LIBRARY_NAME);
CHECK(" LoadLibrary", module != NULL, exit);
/*************************************************************************
* Получить адрес функции запроса структуры с указателями на функции *
*************************************************************************/
getFunctionList = (CK_C_GetFunctionList)GetProcAddress(module, "C_GetFunctionList");
CHECK(" GetProcAddress", getFunctionList != NULL, unload_pkcs11);
/*************************************************************************
* Получить структуру с указателями на функции *
*************************************************************************/
rv = getFunctionList(&functionList);
CHECK_AND_LOG(" Get function list", rv == CKR_OK, rvToStr(rv), unload_pkcs11);
/*************************************************************************
* Инициализировать библиотеку *
*************************************************************************/
rv = functionList->C_Initialize(NULL_PTR);
CHECK_AND_LOG(" C_Initialize", rv == CKR_OK, rvToStr(rv), unload_pkcs11);
/*************************************************************************
* Получить количество слотов c подключенными токенами *
*************************************************************************/
rv = functionList->C_GetSlotList(CK_TRUE, NULL_PTR, &slotCount);
CHECK_AND_LOG(" C_GetSlotList (number of slots)", rv == CKR_OK, rvToStr(rv), finalize_pkcs11);
CHECK_AND_LOG(" Checking available tokens", slotCount > 0, " No tokens available", finalize_pkcs11);
/*************************************************************************
* Получить список слотов c подключенными токенами *
*************************************************************************/
slots = (CK_SLOT_ID_PTR)malloc(slotCount * sizeof(CK_SLOT_ID));
CHECK(" Memory allocation for slots", slots != NULL, finalize_pkcs11);
rv = functionList->C_GetSlotList(CK_TRUE, slots, &slotCount);
CHECK_AND_LOG(" C_GetSlotList", rv == CKR_OK, rvToStr(rv), free_slots);
printf(" Slots available: %d\n", (int)slotCount);
/*************************************************************************
* Получить список поддерживаемых токеном механизмов *
*************************************************************************/
rv = functionList->C_GetMechanismList(slots[0], NULL_PTR, &mechanismCount);
CHECK_AND_LOG(" C_GetMechanismList (number of mechanisms)", rv == CKR_OK, rvToStr(rv), free_slots);
CHECK_AND_LOG(" Checking mechanisms available", mechanismCount > 0, " No mechanisms available", free_slots);
mechanisms = (CK_MECHANISM_TYPE_PTR)malloc(mechanismCount * sizeof(CK_MECHANISM_TYPE));
CHECK(" Memory allocation for mechanisms", mechanisms != NULL_PTR, free_slots);
rv = functionList->C_GetMechanismList(slots[0], mechanisms, &mechanismCount);
CHECK_AND_LOG(" C_GetMechanismList", rv == CKR_OK, rvToStr(rv), free_mechanisms);
/*************************************************************************
* Определение поддерживаемых токеном механизмов *
*************************************************************************/
for (i = 0; i < mechanismCount; ++i) {
if (mechanisms[i] == CKM_GOSTR3411_12_256) {
isGostR3411_12_256Supported = 1;
break;
}
}
CHECK_AND_LOG(" Checking CKM_GOSTR3411_12_256 support", isGostR3411_12_256Supported,
"CKM_GOSTR3411_12_512 isn`t supported!\n", free_mechanisms);
/*************************************************************************
* Открыть RW сессию в первом доступном слоте *
*************************************************************************/
rv = functionList->C_OpenSession(slots[0], CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &session);
CHECK_AND_LOG(" C_OpenSession", rv == CKR_OK, rvToStr(rv), free_mechanisms);
printf("Initialization has been completed successfully.\n");
/*************************************************************************
* Вычислить хэш-код данных *
*************************************************************************/
printf("\nHashing data...\n");
/*************************************************************************
* Инициализировать хэш-функцию *
*************************************************************************/
rv = functionList->C_DigestInit(session, &gostR3411_2012_256HashMech);
CHECK_AND_LOG(" C_DigestInit", rv == CKR_OK, rvToStr(rv), close_session);
/*************************************************************************
* Определить размер хэш-кода *
*************************************************************************/
rv = functionList->C_Digest(session, data, sizeof(data), NULL_PTR, &hashSize);
CHECK_AND_LOG(" C_Digest(get size)", rv == CKR_OK, rvToStr(rv), close_session);
/*************************************************************************
* Вычислить хэш-код данных *
*************************************************************************/
hash = (CK_BYTE_PTR)malloc(hashSize * sizeof(CK_BYTE));
CHECK(" Memory allocation for hash", hash != NULL, close_session);
rv = functionList->C_Digest(session, data, sizeof(data), hash, &hashSize);
CHECK_AND_LOG(" C_Digest (get hash)", rv == CKR_OK, rvToStr(rv), free_hash);
/*************************************************************************
* Распечатать буфер, содержащий хэш-код *
*************************************************************************/
printf(" Hashed buffer is: \n");
printHex(hash, hashSize);
printf("Hashing has been completed.\n");
/*************************************************************************
* Выставить признак успешного завершения программы *
*************************************************************************/
errorCode = 0;
/*************************************************************************
* Выполнить действия для завершения работы с библиотекой PKCS#11 *
*************************************************************************/
printf("\nFinalizing... \n");
/*************************************************************************
* Очистить память, выделенную под хэш-код *
*************************************************************************/
free_hash:
free(hash);
/*************************************************************************
* Закрыть открытую сессию в слоте *
*************************************************************************/
close_session:
rv = functionList->C_CloseSession(session);
CHECK_RELEASE_AND_LOG(" C_CloseSession", rv == CKR_OK, rvToStr(rv), errorCode);
/*************************************************************************
* Очистить память, выделенную под механизмы и слоты *
*************************************************************************/
free_mechanisms:
free(mechanisms);
free_slots:
free(slots);
/*************************************************************************
* Деинициализировать библиотеку *
*************************************************************************/
finalize_pkcs11:
rv = functionList->C_Finalize(NULL_PTR);
CHECK_RELEASE_AND_LOG(" C_Finalize", rv == CKR_OK, rvToStr(rv), errorCode);
/*************************************************************************
* Выгрузить библиотеку из памяти *
*************************************************************************/
unload_pkcs11:
CHECK_RELEASE(" FreeLibrary", FreeLibrary(module), errorCode);
exit:
if (errorCode) {
printf("\n\nSome error occurred. Sample failed.\n");
} else {
printf("\n\nSample has been completed successfully.\n");
}
return errorCode;
}