Поделиться через


Функция CryptSignHashA (wincrypt.h)

Важно Этот API не рекомендуется использовать. Новое и существующее программное обеспечение должно начать использовать API-интерфейсы шифрования следующего поколения. Корпорация Майкрософт может удалить этот API в будущих выпусках.
 
Функция CryptSignHash подписывает данные. Так как все алгоритмы подписи являются асимметричными и, следовательно, медленными, CryptoAPI не позволяет подписывать данные напрямую. Вместо этого сначала хэшируются данные, а для подписывания хэша используется CryptSignHash .

Синтаксис

BOOL CryptSignHashA(
  [in]      HCRYPTHASH hHash,
  [in]      DWORD      dwKeySpec,
  [in]      LPCSTR     szDescription,
  [in]      DWORD      dwFlags,
  [out]     BYTE       *pbSignature,
  [in, out] DWORD      *pdwSigLen
);

Параметры

[in] hHash

Дескриптор хэш-объекта для подписи.

[in] dwKeySpec

Определяет закрытый ключ для использования из контейнера поставщика. Это может быть AT_KEYEXCHANGE или AT_SIGNATURE.

Используемый алгоритм подписи указывается при первоначальном создании пары ключей.

Единственный алгоритм подписи, поддерживаемый поставщиком шифрования Microsoft Base Cryptographic Provider, — это алгоритм открытого ключа RSA.

[in] szDescription

Этот параметр больше не используется и должен иметь значение NULL , чтобы предотвратить уязвимости системы безопасности. Однако он по-прежнему поддерживается для обратной совместимости в базовом поставщике шифрования Майкрософт.

[in] dwFlags

Определены следующие значения флагов.

Значение Значение
CRYPT_NOHASHOID
0x00000001
Используется с поставщиками RSA. Идентификатор хэш-объекта (OID) не помещается в шифрование открытого ключа RSA. Если этот флаг не установлен, хэш-идентификатор идентификатора в сигнатуре по умолчанию соответствует определению DigestInfo в PKCS #1.
CRYPT_TYPE2_FORMAT
0x00000002
Этот флаг не используется.
CRYPT_X931_FORMAT
0x00000004
Используйте метод заполнения подписи RSA, указанный в стандарте ANSI X9.31.

[out] pbSignature

Указатель на буфер, получающий данные сигнатуры.

Этот параметр может иметь значение NULL , чтобы задать размер буфера для целей выделения памяти. Дополнительные сведения см. в разделе Извлечение данных неизвестной длины.

[in, out] pdwSigLen

Указатель на значение DWORD , указывающее размер буфера pbSignature в байтах. Когда функция возвращает значение DWORD , содержит количество байтов, хранящихся в буфере.

Примечание При обработке данных, возвращаемых в буфере, приложения должны использовать фактический размер возвращаемых данных. Фактический размер может быть немного меньше размера буфера, указанного во входных данных. (На входных данных размеры буфера обычно указываются достаточно большими, чтобы убедиться, что максимально возможные выходные данные помещаются в буфер.) В выходных данных переменная, на которую указывает этот параметр, обновляется с учетом фактического размера данных, скопированных в буфер.
 

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

Если функция выполнена успешно, функция возвращает значение TRUE.

Если функция завершается сбоем, она возвращает значение FALSE. Чтобы получить дополнительные сведения об ошибке, вызовите Метод GetLastError.

Коды ошибок, предваряемые "NTE", создаются конкретным поставщиком служб CSP, который вы используете. Ниже приведены некоторые возможные коды ошибок.

Код возврата Описание
ERROR_INVALID_HANDLE
Один из параметров указывает недопустимый дескриптор.
ERROR_INVALID_PARAMETER
Один из параметров содержит недопустимое значение. Чаще всего это недопустимый указатель.
ERROR_MORE_DATA
Буфер, заданный параметром pbSignature , недостаточно велик для хранения возвращаемых данных. Требуемый размер буфера в байтах указан в значении DWORD pdwSigLen.
NTE_BAD_ALGID
Дескриптор hHash указывает алгоритм, который не поддерживается этим поставщиком служб CSP, или параметр dwKeySpec имеет неверное значение.
NTE_BAD_FLAGS
Параметр dwFlags не является нулевым.
NTE_BAD_HASH
Недопустимый хэш-объект, заданный параметром hHash .
NTE_BAD_UID
Не удается найти контекст CSP, указанный при создании хэш-объекта.
NTE_NO_KEY
Закрытый ключ, указанный dwKeySpec , не существует.
NTE_NO_MEMORY
Во время операции у поставщика служб CSP не хватает памяти.

Комментарии

Перед вызовом этой функции необходимо вызвать функцию CryptCreateHash , чтобы получить дескриптор хэш-объекта. Затем функция CryptHashData или CryptHashSessionKey используется для добавления данных или ключей сеанса в хэш-объект. Функция CryptSignHash завершает хэш.

Хотя поставщик служб конфигурации DSS поддерживает хэширование как с помощью алгоритмов MD5, так и с помощью алгоритмов SHA, поставщик служб конфигурации DSS поддерживает только подписывание хэшей SHA.

После вызова этой функции больше нельзя добавить данные в хэш. Сбой дополнительных вызовов CryptHashData или CryptHashSessionKey .

После завершения работы приложения с использованием хэша удалите хэш-объект, вызвав функцию CryptDeographyHash .

По умолчанию поставщики Microsoft RSA используют метод заполнения PKCS #1 для подписи. Хэш-OID в элементе DigestInfo сигнатуры автоматически присваивается идентификатору OID алгоритма, связанному с хэш-объектом. Использование флага CRYPT_NOHASHOID приведет к пропуску этого идентификатора в сигнатуре.

Иногда необходимо подписать хэш-значение, созданное в другом месте. Это можно сделать с помощью следующей последовательности операций:

  1. Создайте хэш-объект с помощью CryptCreateHash.
  2. Задайте хэш-значение в хэш-объекте с помощью значения HP_HASHVAL параметра dwParam в CryptSetHashParam.
  3. Подпишите хэш-значение с помощью CryptSignHash и получите блок цифровой подписи.
  4. Уничтожьте хэш-объект с помощью CryptDeographyHash.

Примеры

В следующем примере показано, как данные подписывания сначала хэшировать данные для подписывания, а затем подписывать хэш с помощью функции CryptSignHash .

//-------------------------------------------------------------
// Declare and initialize variables.

HCRYPTPROV hProv;
BYTE *pbBuffer= (BYTE *)"Sample data that is to be signed.";
DWORD dwBufferLen = strlen((char *)pbBuffer)+1;
HCRYPTHASH hHash;

//--------------------------------------------------------------------
// This code assumes that a cryptographic context handle, hProv,
// and a hash handle, hHash, are available.
// For code needed to acquire the context, see "Example C Program: 
// Signing a Hash and Verifying the Hash Signature."

//--------------------------------------------------------------------
// Compute the cryptographic hash of the buffer.

if(CryptHashData(
   hHash, 
   pbBuffer, 
   dwBufferLen, 
   0)) 
{
     printf("The data buffer has been hashed.\n");
}
else
{
     printf("Error during CryptHashData.\n");
     exit(1);
}
//--------------------------------------------------------------------
// Determine the size of the signature and allocate memory.

dwSigLen= 0;
if(CryptSignHash(
   hHash, 
   AT_SIGNATURE, 
   szDescription, 
   0, 
   NULL, 
   &dwSigLen)) 
{
     printf("Signature length %d found.\n",dwSigLen);
}
else
{
     printf("Error during CryptSignHash\n");
     exit(1);
}
//--------------------------------------------------------------------
// Allocate memory for the signature buffer.

if(pbSignature = (BYTE *)malloc(dwSigLen))
{
     printf("Memory allocated for the signature.\n");
}
else
{
     printf("Out of memory\n");
     exit(1);
}
//--------------------------------------------------------------------
// Sign the hash object.

if(CryptSignHash(
   hHash, 
   AT_SIGNATURE, 
   szDescription, 
   0, 
   pbSignature, 
   &dwSigLen)) 
{
     printf("pbSignature is the hash signature.\n");
}
else
{
     printf("Error during CryptSignHash.\n");
     exit(1);
}
//--------------------------------------------------------------------
// Destroy the hash object.

if(hHash) 
  CryptDestroyHash(hHash);

Полный пример, включая контекст для этого кода, см. в разделе Пример программы C: подписывание хэша и проверка хэш-подписи.

Примечание

Заголовок wincrypt.h определяет CryptSignHash как псевдоним, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора UNICODE. Сочетание использования псевдонима, не зависящий от кодировки, с кодом, не зависящим от кодировки, может привести к несоответствиям, которые приводят к ошибкам компиляции или среды выполнения. Дополнительные сведения см. в разделе Соглашения для прототипов функций.

Требования

Требование Значение
Минимальная версия клиента Windows XP [только классические приложения]
Минимальная версия сервера Windows Server 2003 [только классические приложения]
Целевая платформа Windows
Header wincrypt.h
Библиотека Advapi32.lib
DLL Advapi32.dll

См. также раздел

CryptCreateHash

CryptDeographyHash

CryptHashData

CryptHashSessionKey

CryptVerifySignature

Функции хэша и цифровой подписи