CryptSignHashW function (wincrypt.h)

Important  This API is deprecated. New and existing software should start using Cryptography Next Generation APIs. Microsoft may remove this API in future releases.
 
The CryptSignHash function signs data. Because all signature algorithms are asymmetric and thus slow, CryptoAPI does not allow data to be signed directly. Instead, data is first hashed, and CryptSignHash is used to sign the hash.

Syntax

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

Parameters

[in] hHash

Handle of the hash object to be signed.

[in] dwKeySpec

Identifies the private key to use from the provider's container. It can be AT_KEYEXCHANGE or AT_SIGNATURE.

The signature algorithm used is specified when the key pair is originally created.

The only signature algorithm that the Microsoft Base Cryptographic Provider supports is the RSA Public Key algorithm.

[in] szDescription

This parameter is no longer used and must be set to NULL to prevent security vulnerabilities. However, it is still supported for backward compatibility in the Microsoft Base Cryptographic Provider.

[in] dwFlags

The following flag values are defined.

Value Meaning
CRYPT_NOHASHOID
0x00000001
Used with RSA providers. The hash object identifier (OID) is not placed in the RSA public key encryption. If this flag is not set, the hash OID in the default signature is as specified in the definition of DigestInfo in PKCS #1.
CRYPT_TYPE2_FORMAT
0x00000002
This flag is not used.
CRYPT_X931_FORMAT
0x00000004
Use the RSA signature padding method specified in the ANSI X9.31 standard.

[out] pbSignature

A pointer to a buffer receiving the signature data.

This parameter can be NULL to set the buffer size for memory allocation purposes. For more information, see Retrieving Data of Unknown Length.

[in, out] pdwSigLen

A pointer to a DWORD value that specifies the size, in bytes, of the pbSignature buffer. When the function returns, the DWORD value contains the number of bytes stored in the buffer.

Note  When processing the data returned in the buffer, applications must use the actual size of the data returned. The actual size can be slightly smaller than the size of the buffer specified on input. (On input, buffer sizes are usually specified large enough to ensure that the largest possible output data fits in the buffer.) On output, the variable pointed to by this parameter is updated to reflect the actual size of the data copied to the buffer.
 

Return value

If the function succeeds, the function returns TRUE.

If the function fails, it returns FALSE. For extended error information, call GetLastError.

The error codes prefaced by "NTE" are generated by the particular CSP you are using. Some possible error codes follow.

Return code Description
ERROR_INVALID_HANDLE
One of the parameters specifies a handle that is not valid.
ERROR_INVALID_PARAMETER
One of the parameters contains a value that is not valid. This is most often a pointer that is not valid.
ERROR_MORE_DATA
The buffer specified by the pbSignature parameter is not large enough to hold the returned data. The required buffer size, in bytes, is in the pdwSigLenDWORD value.
NTE_BAD_ALGID
The hHash handle specifies an algorithm that this CSP does not support, or the dwKeySpec parameter has an incorrect value.
NTE_BAD_FLAGS
The dwFlags parameter is nonzero.
NTE_BAD_HASH
The hash object specified by the hHash parameter is not valid.
NTE_BAD_UID
The CSP context that was specified when the hash object was created cannot be found.
NTE_NO_KEY
The private key specified by dwKeySpec does not exist.
NTE_NO_MEMORY
The CSP ran out of memory during the operation.

Remarks

Before calling this function, the CryptCreateHash function must be called to get a handle to a hash object. The CryptHashData or CryptHashSessionKey function is then used to add the data or session keys to the hash object. The CryptSignHash function completes the hash.

While the DSS CSP supports hashing with both the MD5 and the SHA hash algorithms, the DSS CSP only supports signing SHA hashes.

After this function is called, no more data can be added to the hash. Additional calls to CryptHashData or CryptHashSessionKey fail.

After the application finishes using the hash, destroy the hash object by calling the CryptDestroyHash function.

By default, the Microsoft RSA providers use the PKCS #1 padding method for the signature. The hash OID in the DigestInfo element of the signature is automatically set to the algorithm OID associated with the hash object. Using the CRYPT_NOHASHOID flag will cause this OID to be omitted from the signature.

Occasionally, a hash value that has been generated elsewhere must be signed. This can be done by using the following sequence of operations:

  1. Create a hash object by using CryptCreateHash.
  2. Set the hash value in the hash object by using the HP_HASHVAL value of the dwParam parameter in CryptSetHashParam.
  3. Sign the hash value by using CryptSignHash and obtain a digital signature block.
  4. Destroy the hash object by using CryptDestroyHash.

Examples

The following example shows signing data by first hashing the data to be signed and then signing the hash by using the CryptSignHash function.

//-------------------------------------------------------------
// 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);

For a complete example including the context for this code, see Example C Program: Signing a Hash and Verifying the Hash Signature.

Note

The wincrypt.h header defines CryptSignHash as an alias that automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that is not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for Function Prototypes.

Requirements

Requirement Value
Minimum supported client Windows XP [desktop apps only]
Minimum supported server Windows Server 2003 [desktop apps only]
Target Platform Windows
Header wincrypt.h
Library Advapi32.lib
DLL Advapi32.dll

See also

CryptCreateHash

CryptDestroyHash

CryptHashData

CryptHashSessionKey

CryptVerifySignature

Hash and Digital Signature Functions