CryptCreateHash
CryptCreateHash — это функция из состава криптографического интерфейса Microsoft CryptoAPI, предназначенная для инициализации хэш-объекта. Она создаёт дескриптор пустого хэша, который затем может быть заполнен данными для последующего вычисления хэш-значения (дайджеста) с использованием заданного алгоритма. Функция является частью стандартного набора криптографических средств операционных систем семейства Microsoft Windows, начиная с версий Windows 2000 и Windows NT 4.0 с пакетом обновлений.
Назначение и область применения
Функция CryptCreateHash используется в процессах, где требуется проверка целостности данных, аутентификация сообщений, создание цифровых подписей или хранение паролей в виде хэшей. Она применяется как в системных компонентах Windows (например, при проверке целостности системных файлов, в службах шифрования дисков BitLocker), так и в сторонних приложениях, работающих с криптографией — от антивирусных программ до средств электронного документооборота. Функция поддерживает широкий спектр алгоритмов хэширования, включая MD2, MD4, MD5, SHA-1, SHA-256, SHA-384, SHA-512, а также алгоритмы, реализованные через сторонние криптопровайдеры.
Синтаксис и параметры
Функция объявлена в заголовочном файле wincrypt.h и доступна через библиотеку advapi32.dll. Её прототип на языке C выглядит следующим образом:
``c BOOL CryptCreateHash( HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DWORD dwFlags, HCRYPTHASH *phHash ); ``
Параметры
- hProv — дескриптор криптопровайдера (CSP), полученный ранее через вызов
CryptAcquireContext. Этот дескриптор определяет, какой именно криптопровайдер будет использоваться для вычисления хэша. В системах Windows по умолчанию доступны провайдеры Microsoft Base Cryptographic Provider, Microsoft Enhanced Cryptographic Provider и Microsoft Strong Cryptographic Provider, различающиеся набором поддерживаемых алгоритмов и длиной ключей. - Algid — идентификатор алгоритма хэширования (тип
ALG_ID). Стандартные значения включают: CALG_MD2— алгоритм MD2 (128-битный дайджест);CALG_MD4— алгоритм MD4 (128-битный дайджест);CALG_MD5— алгоритм MD5 (128-битный дайджест);CALG_SHA1— алгоритм SHA-1 (160-битный дайджест);CALG_SHA_256— алгоритм SHA-256 (256-битный дайджест);CALG_SHA_384— алгоритм SHA-384 (384-битный дайджест);CALG_SHA_512— алгоритм SHA-512 (512-битный дайджест).- hKey — дескриптор ключа, используемый для создания хэша с ключом (keyed hash). Если хэш не требует ключа (например, для простого хэширования данных), этот параметр должен быть равен 0. При создании хэша с ключом (например, для HMAC) передаётся дескриптор симметричного ключа, полученного через
CryptGenKeyилиCryptImportKey. - dwFlags — флаги, определяющие дополнительные параметры создания хэша. В текущей реализации Microsoft CryptoAPI единственным определённым значением является
CRYPT_CREATE_SALT(0x00000004), который указывает, что провайдер должен самостоятельно сгенерировать соль для хэша. В большинстве случаев этот параметр устанавливается в 0. - phHash — указатель на переменную типа
HCRYPTHASH, в которую функция записывает дескриптор созданного хэш-объекта. Этот дескриптор затем используется в других функциях CryptoAPI, таких какCryptHashData,CryptGetHashParamиCryptDestroyHash.
Возвращаемое значение
Функция возвращает TRUE в случае успешного выполнения и FALSE при ошибке. Код ошибки можно получить с помощью функции GetLastError. Наиболее распространённые коды ошибок:
NTE_BAD_ALGID— указан неподдерживаемый или неверный идентификатор алгоритма;NTE_BAD_FLAGS— указаны недопустимые флаги;NTE_BAD_KEY— передан недопустимый дескриптор ключа;NTE_BAD_UID— недопустимый дескриптор криптопровайдера;ERROR_INVALID_PARAMETER— один из параметров содержит недопустимое значение.
Порядок использования
Работа с функцией CryptCreateHash в типичном сценарии включает следующие этапы:
- Получение дескриптора криптопровайдера — вызов
CryptAcquireContextс указанием имени провайдера и типа контейнера. - Создание хэш-объекта — вызов
CryptCreateHashс полученным дескриптором провайдера и идентификатором алгоритма. - Добавление данных в хэш — один или несколько вызовов
CryptHashData, передающих фрагменты данных, которые должны быть захэшированы. - Извлечение хэш-значения — вызов
CryptGetHashParamс параметромHP_HASHVALдля получения вычисленного дайджеста. - Освобождение ресурсов — вызов
CryptDestroyHashдля уничтожения хэш-объекта иCryptReleaseContextдля освобождения дескриптора провайдера.
Особенности и ограничения
- Функция CryptCreateHash не выполняет самого хэширования — она лишь создаёт объект, готовый к приёму данных. Само вычисление происходит при вызове
CryptHashData. - При использовании хэша с ключом (параметр
hKeyне равен 0) создаётся ключевой хэш (keyed hash), который может использоваться для аутентификации сообщений (MAC). Однако для создания HMAC (Hash-based Message Authentication Code) в современных версиях Windows рекомендуется использовать более новый интерфейс Cryptography API: Next Generation (CNG), так как реализация HMAC через CryptoAPI имеет ограничения по длине ключа. - Функция не поддерживает создание хэшей для потоковой обработки данных в режиме реального времени — все данные должны быть переданы до извлечения результата. Однако многократные вызовы
CryptHashDataпозволяют обрабатывать данные по частям. - В Windows Vista и более новых версиях Microsoft рекомендует использовать CNG API (функции типа
BCryptCreateHash) вместо CryptoAPI, так как CryptoAPI считается устаревшим, хотя и продолжает поддерживаться для обратной совместимости.
Пример использования
Ниже приведён упрощённый пример на языке C, демонстрирующий вычисление SHA-256 хэша для строки:
```c
include <windows.h>
include <wincrypt.h>
include <stdio.h>
int main() { HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; BYTE *pbData = "Hello, World!"; DWORD dwDataLen = 13; BYTE rgbHash[32]; DWORD cbHash = 32; DWORD i;
// Получение дескриптора провайдера if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { printf("Ошибка CryptAcquireContext: %x\n", GetLastError()); return 1; }
// Создание хэш-объекта SHA-256 if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) { printf("Ошибка CryptCreateHash: %x\n", GetLastError()); CryptReleaseContext(hProv, 0); return 1; }
// Добавление данных if (!CryptHashData(hHash, pbData, dwDataLen, 0)) { printf("Ошибка CryptHashData: %x\n", GetLastError()); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return 1; }
// Извлечение хэша if (!CryptGetHashParam(hHash, HP_HASHVAL, rgbHash, &cbHash, 0)) { printf("Ошибка CryptGetHashParam: %x\n", GetLastError()); CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return 1; }
// Вывод хэша в шестнадцатеричном виде for (i = 0; i < cbHash; i++) { printf("%02x", rgbHash[i]); } printf("\n");
// Очистка CryptDestroyHash(hHash); CryptReleaseContext(hProv, 0); return 0; } ```
Безопасность и криптостойкость
- Алгоритмы MD2, MD4 и MD5, поддерживаемые функцией, считаются криптографически устаревшими и не рекомендуются к использованию в новых разработках из-за известных уязвимостей (коллизий). Для обеспечения безопасности следует применять алгоритмы семейства SHA-2 (SHA-256, SHA-384, SHA-512).
- Функция не предоставляет встроенной защиты от атак по сторонним каналам (side-channel attacks). В высоконагруженных или критических средах рекомендуется использовать CNG API, где доступны более защищённые реализации.
- Дескриптор хэш-объекта должен быть уничтожен после использования вызовом
CryptDestroyHashво избежание утечки памяти. В противном случае возможна постепенная деградация производительности системы.
Источники
- Microsoft Docs. «CryptCreateHash function (wincrypt.h)». — Документация по API Windows.
- MSDN Magazine. «Cryptography in Windows: CryptoAPI vs. CNG». — Обзор криптографических интерфейсов Windows.
- Шнайер Б. «Прикладная криптография». — Глава 18: Хэш-функции и аутентификация сообщений.
- Ferguson N., Schneier B., Kohno T. «Cryptography Engineering». — Раздел 6.3: Хэш-функции в Windows.
- Ресурсы Microsoft Developer Network (MSDN) — примеры использования CryptoAPI.
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →