CryptSignHashA 函式 (wincrypt.h)

重要 此 API 已被取代。 新的和現有的軟體應該開始使用 密碼編譯新一代 API。 Microsoft 可能會在未來的版本中移除此 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 密碼編譯提供者支援的唯一簽章演算法是 RSA 公鑰演演算法。

[in] szDescription

這個參數不再使用,而且必須設定為 NULL 以防止安全性弱點。 不過,在 Microsoft 基底密碼編譯提供者中仍支援回溯相容性。

[in] dwFlags

定義下列旗標值。

意義
CRYPT_NOHASHOID
0x00000001
與 RSA 提供者搭配使用。 OID) (哈希 對象識別碼 不會放在 RSA 公鑰加密中。 如果未設定此旗標,預設簽章中的哈希 OID 會如 PKCS 中 DigestInfo 的定義中所指定 #1 所指定。
CRYPT_TYPE2_FORMAT
0x00000002
未使用此旗標。
CRYPT_X931_FORMAT
0x00000004
使用 ANSI X9.31 標準中指定的 RSA 簽章填補方法。

[out] pbSignature

接收簽章數據的緩衝區指標。

此參數可以是 NULL ,可設定記憶體配置用途的緩衝區大小。 如需詳細資訊,請參閱 擷取未知長度的數據

[in, out] pdwSigLen

DWORD 值的指標,指定 pbSignature 緩衝區的大小,以位元組為單位。 當函式傳回時, DWORD 值會包含儲存在緩衝區中的位元元組數目。

注意 處理緩衝區中傳回的數據時,應用程式必須使用傳回之數據的實際大小。 實際大小可能比輸入上指定的緩衝區大小稍微小一點。 (輸入時,通常會指定足夠的緩衝區大小,以確保最大可能的輸出數據符合 buffer.) On 輸出中,此參數所指向的變數會更新,以反映複製到緩衝區的數據的實際大小。
 

傳回值

如果函式成功,函式會傳回 TRUE

如果函式失敗,則會傳回 FALSE。 如需擴充錯誤資訊,請呼叫 GetLastError

“NTE” 開頭的錯誤碼是由您使用的特定 CSP 所產生。 以下是一些可能的錯誤碼。

傳回碼 Description
ERROR_INVALID_HANDLE
其中一個參數指定無效的句柄。
ERROR_INVALID_PARAMETER
其中一個參數包含無效的值。 這通常是無效的指標。
ERROR_MORE_DATA
pbSignature 參數指定的緩衝區不夠大,無法保存傳回的數據。 所需的緩衝區大小,以位元組為單位,位於 pdwSigLenDWORD 值中。
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 函式,才能取得哈希物件的句柄。 CryptHashDataCryptHashSessionKey 函式接著會用來將數據或會話索引鍵新增至哈希物件。 CryptSignHash 函式會完成哈希。

雖然 DSS CSP 同時支援使用 MD5 和 SHA 哈希演算法進行哈希,但 DSS CSP 僅支援簽署 SHA 哈希。

呼叫此函式之後,就無法再將數據新增至哈希。 對 CryptHashDataCryptHashSessionKey 的其他呼叫會失敗。

應用程式使用哈希完成之後,呼叫 CryptDestroyHash 函式來終結哈希物件。

根據預設,Microsoft RSA 提供者會針對簽章使用 PKCS #1 填補方法。 簽章 之 DigestInfo 元素中的哈希 OID 會自動設定為與哈希對象相關聯的演算法 OID。 使用 CRYPT_NOHASHOID 旗標會導致此 OID 從簽章中省略。

有時候,其他位置產生的哈希值必須經過簽署。 這可以使用下列作業順序來完成:

  1. 使用 CryptCreateHash 建立哈希物件。
  2. 使用 CryptSetHashParamdwParam 參數的HP_HASHVAL值,在哈希對象中設定哈希值。
  3. 使用 CryptSignHash 簽署哈希值,並取得數位簽名區塊。
  4. 使用 CryptDestroyHash 終結哈希物件。

範例

下列範例會先哈希要簽署的數據,然後使用 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 定義為別名,根據 UNICODE 預處理器常數的定義,自動選取此函式的 ANSI 或 Unicode 版本。 混合使用編碼中性別名與非編碼中性的程序代碼,可能會導致編譯或運行時間錯誤不符。 如需詳細資訊,請參閱 函式原型的慣例

規格需求

需求
最低支援的用戶端 Windows XP [僅限傳統型應用程式]
最低支援的伺服器 Windows Server 2003 [僅限傳統型應用程式]
目標平台 Windows
標頭 wincrypt.h
程式庫 Advapi32.lib
Dll Advapi32.dll

另請參閱

CryptCreateHash

CryptDestroyHash

CryptHashData

CryptHashSessionKey

CryptVerifySignature

哈希和數位簽名函式