Открыть сервис

CryptGetHashParam

CryptGetHashParam — это функция из набора криптографических API (CryptoAPI) операционной системы Microsoft Windows, предназначенная для извлечения параметров хэш-объекта, созданного с помощью функции CryptCreateHash. Функция позволяет получить значения, такие как размер хэша, сам хэш (результат вычисления), а также дополнительные атрибуты, связанные с алгоритмом хэширования. Она входит в состав библиотеки advapi32.dll и используется в процессах цифровой подписи, проверки целостности данных и аутентификации.

История

Функция CryptGetHashParam была введена в Microsoft Windows 2000 как часть CryptoAPI 2.0. CryptoAPI, разработанный корпорацией Microsoft, предоставлял унифицированный интерфейс для криптографических операций, включая хэширование, шифрование и подпись данных. В более поздних версиях Windows, включая Windows XP, Windows 7 и Windows 10, функция оставалась совместимой, но с добавлением поддержки новых алгоритмов, таких как SHA-2 (SHA-256, SHA-384, SHA-512) и SHA-3 (в Windows 10 версии 1903 и выше). В Windows 8 и более новых версиях Microsoft рекомендовала использовать более современные API, такие как CNG (Cryptography Next Generation), но CryptGetHashParam сохранила обратную совместимость для старых приложений.

Синтаксис и параметры

Функция объявлена в заголовочном файле wincrypt.h и имеет следующий прототип на языке C:

``c BOOL CryptGetHashParam( HCRYPTHASH hHash, DWORD dwParam, BYTE pbData, DWORD pdwDataLen, DWORD dwFlags ); ``

Параметры

  • hHash: Дескриптор (HCRYPTHASH) хэш-объекта, полученный ранее через CryptCreateHash. Дескриптор должен быть действительным и не закрытым.
  • dwParam: Идентификатор запрашиваемого параметра. Возможные значения:
  • HP_HASHVAL (0x0002): Получить вычисленное значение хэша (результат хэширования). После вызова функции в буфер pbData записывается хэш-код.
  • HP_HASHSIZE (0x0004): Получить размер хэша в байтах. Возвращает целое число, соответствующее длине хэша (например, 20 для SHA-1, 32 для SHA-256).
  • HP_ALGID (0x0001): Получить идентификатор алгоритма хэширования (ALG_ID), используемого в объекте.
  • HP_HASHSTART (0x0008): Получить начальное состояние хэш-объекта (используется для возобновления хэширования).
  • pbData: Указатель на буфер, в который будут записаны данные. Если параметр dwParam равен HP_HASHSIZE, буфер должен содержать переменную типа DWORD. Для HP_HASHVAL буфер должен быть достаточного размера для хранения хэша.
  • pdwDataLen: Указатель на переменную типа DWORD, которая при вызове содержит размер буфера pbData в байтах. После успешного выполнения функция записывает сюда фактическое количество записанных байт. Для HP_HASHSIZE это значение равно 4 (размер DWORD).
  • dwFlags: Зарезервированный параметр, должен быть равен 0.

Возвращаемое значение

Функция возвращает ненулевое значение (TRUE) в случае успеха. При ошибке возвращается ноль (FALSE), и для получения кода ошибки следует вызвать GetLastError. Типичные ошибки:

  • NTE_BAD_HASH: Неверный дескриптор хэш-объекта.
  • ERROR_MORE_DATA: Буфер pbData слишком мал для запрашиваемых данных (для HP_HASHVAL).
  • NTE_BAD_FLAGS: Неверный параметр dwParam.

Использование

Получение хэша данных

Наиболее распространённое применение CryptGetHashParam — извлечение результата хэширования после добавления данных через CryptHashData. Пример последовательности:

  1. Открытие криптопровайдера (CSP) с помощью CryptAcquireContext.
  2. Создание хэш-объекта через CryptCreateHash с указанием алгоритма (например, CALG_SHA1).
  3. Добавление данных для хэширования через CryptHashData.
  4. Вызов CryptGetHashParam с параметром HP_HASHVAL для получения хэша.
  5. Закрытие хэш-объекта через CryptDestroyHash и освобождение контекста.

Пример кода (C++)

```cpp

include <windows.h>

include <wincrypt.h>

include <stdio.h>

void GetHashExample() { HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; BYTE pbData[] = "Hello, World!"; DWORD dwDataLen = sizeof(pbData) - 1; // без нулевого терминатора BYTE pbHash[32]; // достаточно для SHA-256 DWORD dwHashLen = sizeof(pbHash);

// Получение контекста CSP if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { printf("Ошибка CryptAcquireContext: %x\n", GetLastError()); return; }

// Создание хэш-объекта SHA-256 if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) { printf("Ошибка CryptCreateHash: %x\n", GetLastError()); CryptReleaseContext(hProv, 0); return; }

// Добавление данных if (!CryptHashData(hHash, pbData, dwDataLen, 0)) { printf("Ошибка CryptHashData: %x\n", GetLastError()); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return; }

// Получение хэша if (!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) { printf("Ошибка CryptGetHashParam: %x\n", GetLastError()); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return; }

// Вывод хэша в шестнадцатеричном формате printf("Хэш: "); for (DWORD i = 0; i < dwHashLen; i++) { printf("%02x", pbHash[i]); } printf("\n");

// Очистка CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); } ```

Получение размера хэша

Для определения длины хэша без выделения буфера можно использовать HP_HASHSIZE:

``c DWORD dwHashSize; DWORD dwSize = sizeof(dwHashSize); CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&dwHashSize, &dwSize, 0); // dwHashSize содержит размер хэша в байтах ``

Особенности и ограничения

  • Требование к буферу: Для HP_HASHVAL буфер должен быть достаточного размера. Рекомендуется сначала запросить размер через HP_HASHSIZE, затем выделить память. Максимальный размер хэша для современных алгоритмов (например, SHA-512) составляет 64 байта.
  • Состояние хэш-объекта: После вызова CryptGetHashParam с HP_HASHVAL хэш-объект остаётся в состоянии, пригодном для добавления новых данных (если не был вызван CryptHashData с флагом завершения). Однако для получения окончательного хэша рекомендуется завершить хэширование.
  • Безопасность: Функция не поддерживает многопоточность на одном дескрипторе. Для параллельных операций следует создавать отдельные хэш-объекты.
  • Устаревание: В Windows 8 и выше Microsoft рекомендует использовать CNG API, в частности функцию BCryptFinishHash для получения хэша. Однако CryptGetHashParam остаётся доступной для совместимости.

Применение

CryptGetHashParam используется в:

  • Цифровых подписях: Для получения хэша сообщения перед подписанием через CryptSignHash.
  • Проверке целостности: Сравнение вычисленного хэша с эталонным значением (например, для проверки файлов).
  • Аутентификации: В протоколах, где требуется хэширование паролей или ключей.
  • Криптографических утилитах: В программах для генерации контрольных сумм (например, MD5, SHA-1, SHA-256).

Альтернативы

В современных версиях Windows (начиная с Windows 8) предпочтительным является использование CNG:

  • BCryptCreateHash — создание хэш-объекта.
  • BCryptHashData — добавление данных.
  • BCryptFinishHash — получение хэша.

Для кроссплатформенных решений часто применяются библиотеки OpenSSL, libsodium или Crypto++.

Источники

  • Microsoft Developer Network (MSDN): документация по функции CryptGetHashParam.
  • "Windows Cryptography API: Next Generation" (Microsoft Press, 2010).
  • "Programming Windows Security" (Keith Brown, 2000).
  • Стандарты NIST: FIPS 180-4 (SHA-1, SHA-2), FIPS 202 (SHA-3).

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →