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. Пример последовательности:
- Открытие криптопровайдера (CSP) с помощью CryptAcquireContext.
- Создание хэш-объекта через CryptCreateHash с указанием алгоритма (например, CALG_SHA1).
- Добавление данных для хэширования через CryptHashData.
- Вызов CryptGetHashParam с параметром
HP_HASHVALдля получения хэша. - Закрытие хэш-объекта через 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 →