Export (0) Print
Expand All
Expand Minimize
1 out of 3 rated this helpful - Rate this topic

CryptSignHash function

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 WINAPI CryptSignHash(
  _In_     HCRYPTHASH hHash,
  _In_     DWORD dwKeySpec,
  _In_     LPCTSTR sDescription,
  _In_     DWORD dwFlags,
  _Out_    BYTE *pbSignature,
  _Inout_  DWORD *pdwSigLen
);

Parameters

hHash [in]

Handle of the hash object to be signed.

dwKeySpec [in]

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.

sDescription [in]

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.

dwFlags [in]

The following flag values are defined.

ValueMeaning
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.

 

pbSignature [out]

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.

pdwSigLen [in, out]

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 codeDescription
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.

Requirements

Minimum supported client

Windows XP [desktop apps only]

Minimum supported server

Windows Server 2003 [desktop apps only]

Header

Wincrypt.h

Library

Advapi32.lib

DLL

Advapi32.dll

Unicode and ANSI names

CryptSignHashW (Unicode) and CryptSignHashA (ANSI)

See also

Hash and Digital Signature Functions
CryptCreateHash
CryptDestroyHash
CryptHashData
CryptHashSessionKey
CryptVerifySignature

 

 

Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback

Community Additions

ADD
Show:
© 2014 Microsoft. All rights reserved.