CryptSignHashA function (wincrypt.h)
Syntax
BOOL CryptSignHashA(
[in] HCRYPTHASH hHash,
[in] DWORD dwKeySpec,
[in] LPCSTR 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 |
---|---|
|
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. |
|
This flag is not used. |
|
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.
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 |
---|---|
|
One of the parameters specifies a handle that is not valid. |
|
One of the parameters contains a value that is not valid. This is most often a pointer that is not valid. |
|
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. |
|
The hHash handle specifies an algorithm that this CSP does not support, or the dwKeySpec parameter has an incorrect value. |
|
The dwFlags parameter is nonzero. |
|
The hash object specified by the hHash parameter is not valid. |
|
The CSP context that was specified when the hash object was created cannot be found. |
|
The private key specified by dwKeySpec does not exist. |
|
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:
- Create a hash object by using CryptCreateHash.
- Set the hash value in the hash object by using the HP_HASHVAL value of the dwParam parameter in CryptSetHashParam.
- Sign the hash value by using CryptSignHash and obtain a digital signature block.
- 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 which 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 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 |