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


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

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

Синтаксис

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

Параметры

[in] hHash

Дескриптор хэш-объекта , который должен быть подписан.

[in] dwKeySpec

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

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

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

[in] szDescription

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

[in] dwFlags

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

Ценность Значение
CRYPT_NOHASHOID
0x00000001
Используется с поставщиками RSA. Хэш-идентификатор объекта (OID) не помещается в шифрование открытого ключа RSA. Если этот флаг не задан, хэш-идентификатор OID в сигнатуре по умолчанию указан в определении 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, недостаточно велик для хранения возвращаемых данных. Требуемый размер буфера в байтах находится в значении pdwSigLenDWORD.
NTE_BAD_ALGID
Дескриптор hHash 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 завершает хэш.

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

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

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

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

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

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

Примеры

В следующем примере показаны данные подписывания, сначала хэшируя данные для подписывания, а затем подписывая хэш с помощью функции 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 или Юникод этой функции на основе определения константы препроцессора ЮНИКОДа. Сочетание использования псевдонима, нейтрального для кодирования, с кодом, не зависящим от кодирования, может привести к несоответствиям, которые приводят к ошибкам компиляции или среды выполнения. Дополнительные сведения см. в соглашениях о прототипах функций.

Требования

Требование Ценность
минимальные поддерживаемые клиентские Windows XP [только классические приложения]
минимальный поддерживаемый сервер Windows Server 2003 [только классические приложения]
целевая платформа Виндоус
заголовка wincrypt.h
библиотеки Advapi32.lib
DLL Advapi32.dll

См. также

CryptCreateHash

CryptDeskHash

CryptHashData

CryptHashSessionKey

CryptVerifySignature

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