CryptDecrypt 函式 (wincrypt.h)

重要 此 API 已被取代。 新的和現有的軟體應該開始使用 密碼編譯新一代 API。 Microsoft 可能會在未來的版本中移除此 API。
 
CryptDecrypt函式會使用CryptEncrypt函式解密先前加密的資料。

支援 Secure/Multipurpose Internet Mail Extensions (S/MIME) 電子郵件互通性的重要變更,已對影響信封郵件處理的 CryptoAPI 進行。 如需詳細資訊,請參閱 CryptMsgOpenToEncode的一節。

語法

BOOL CryptDecrypt(
  [in]      HCRYPTKEY  hKey,
  [in]      HCRYPTHASH hHash,
  [in]      BOOL       Final,
  [in]      DWORD      dwFlags,
  [in, out] BYTE       *pbData,
  [in, out] DWORD      *pdwDataLen
);

參數

[in] hKey

要用於解密之金鑰的控制碼。 應用程式會使用 CryptGenKeyCryptImportKey 函式來取得此控制碼。

此金鑰會指定要使用的解密演算法。

[in] hHash

雜湊物件的控制碼。 如果要同時解密和雜湊資料,則會在此參數中傳遞雜湊物件的控制碼。 雜湊值會以解密的 純文字進行更新。 此選項在同時解密和驗證簽章時很有用。

呼叫 CryptDecrypt之前,應用程式必須藉由呼叫 CryptCreateHash 函式來取得雜湊物件的控制碼。 解密完成之後,可以使用CryptGetHashParam函式來取得雜湊值,也可以使用CryptSignHash函式進行簽署,或使用CryptVerifySignature函式來驗證數位簽章

如果未完成雜湊,此參數必須為零。

[in] Final

布林值,指定這是否為解密數列中的最後一個區段。 如果此值是最後或唯一的區塊,則此值為 TRUE 。 如果這不是最後一個區塊,則此值為 FALSE。 如需詳細資訊,請參閱<備註>。

[in] dwFlags

定義下列旗標值。

意義
CRYPT_OAEP
0x00000040
使用最佳非對稱加密填補 (OAEP) (PKCS #1 第 2 版) 。 只有具有 RSA 加密/解密的 Microsoft 增強式密碼編譯提供者 才支援此旗標。 此旗標無法與 CRYPT_DECRYPT_RSA_NO_PADDING_CHECK 旗標結合。
CRYPT_DECRYPT_RSA_NO_PADDING_CHECK
0x00000020
BLOB 上執行解密,而不檢查填補。 只有具有 RSA 加密/解密的 Microsoft 增強式密碼編譯提供者 才支援此旗標。 此旗標無法與 CRYPT_OAEP 旗標結合。

[in, out] pbData

緩衝區的指標,其中包含要解密的資料。 執行解密之後,純文字會放回這個相同的緩衝區。

這個緩衝區中的加密位元組數目是由 pdwDataLen所指定。

[in, out] pdwDataLen

DWORD值的指標,指出pbData緩衝區的長度。 呼叫此函式之前,呼叫的應用程式會將 DWORD 值設定為要解密的位元組數目。 傳回時, DWORD 值會包含解密純文字的位元組數目。

使用 區塊加密 時,除非這是要解密之資料的最後一節,否則此資料長度必須是區塊大小的倍數, 而且 Final 參數為 TRUE

傳回值

如果函式成功,函式會傳回非零 (TRUE) 。

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

NTE 前面出現的錯誤碼是由所使用的特定 CSP 所產生。 以下是一些可能的錯誤碼。

描述
ERROR_INVALID_HANDLE
其中一個參數指定不正確控制碼。
ERROR_INVALID_PARAMETER
其中一個參數包含不正確值。 這通常是不正確指標。
NTE_BAD_ALGID
hKey工作階段金鑰指定此 CSP 不支援的演算法。
NTE_BAD_DATA
要解密的資料無效。 例如,使用區塊加密且 [最終 ] 旗標為 FALSE時, pdwDataLen 所指定的值必須是區塊大小的倍數。 當找到 填補 無效時,也可以傳回此錯誤。
NTE_BAD_FLAGS
dwFlags參數為非零。
NTE_BAD_HASH
hHash參數包含不正確控制碼。
NTE_BAD_KEY
hKey參數不包含金鑰的有效控制碼。
NTE_BAD_LEN
輸出緩衝區的大小太小,無法保存產生的純文字。
NTE_BAD_UID
找不到建立金鑰時指定的 CSP 內容。
NTE_DOUBLE_ENCRYPT
應用程式嘗試解密相同的資料兩次。
NTE_FAIL
函式以非預期的方式失敗。

備註

如果要解密大量資料,則可以在區段中重複呼叫 CryptDecrypt 來完成。 Final參數必須只在最後一次呼叫CryptDecrypt時設定為TRUE,以便解密引擎可以正確完成解密程式。 當 FinalTRUE時,會執行下列額外動作:

  • 如果金鑰是區塊加密金鑰,資料會填補到加密的多個區塊大小。 若要尋找加密的區塊大小,請使用 CryptGetKeyParam 來取得索引鍵的KP_BLOCKLEN值。
  • 如果加密是以 鏈結模式運作,下一個 CryptDecrypt 作業會將加密的意見反應暫存器重設為金鑰的KP_IV值。
  • 如果加密是 資料流程加密,下一個 CryptDecrypt 呼叫會將加密重設為其初始 狀態

沒有辦法將加密的意見反應註冊為索引鍵的KP_IV值,而不將 Final 參數設定為 TRUE。 如果需要這樣做,如同您不想新增額外的填補區塊或變更每個區塊的大小,您可以使用 CryptDuplicateKey 函式建立原始索引鍵的複本,並將重複的索引鍵傳遞至 CryptDecrypt 函式來模擬。 這會導致原始索引鍵的KP_IV放在重複的索引鍵中。 建立或匯入原始金鑰之後,您無法使用原始金鑰進行加密,因為金鑰的意見反應暫存器將會變更。 下列虛擬程式碼示範如何完成此作業。

// Set the IV for the original key. Do not use the original key for 
// encryption or decryption after doing this because the key's 
// feedback register will get modified and you cannot change it.
CryptSetKeyParam(hOriginalKey, KP_IV, newIV)

while(block = NextBlock())
{
    // Create a duplicate of the original key. This causes the 
    // original key's IV to be copied into the duplicate key's 
    // feedback register.
    hDuplicateKey = CryptDuplicateKey(hOriginalKey)

    // Decrypt the block with the duplicate key.
    CryptDecrypt(hDuplicateKey, block)

    // Destroy the duplicate key. Its feedback register has been 
    // modified by the CryptEncrypt function, so it cannot be used
    // again. It will be re-duplicated in the next iteration of the 
    // loop.
    CryptDestroyKey(hDuplicateKey)
}

Microsoft 增強式密碼編譯提供者支援使用RSA公開金鑰進行直接加密,並使用 RSA私密金鑰進行解密。 加密會使用 PKCS #1 填補。 在解密時,會驗證此填補。 要解密的 加密文字 資料長度必須與用來解密資料的 RSA 金鑰模數相同。 如果加密文字在最重要的位元組中具有零,這些位元組必須包含在輸入資料緩衝區和輸入緩衝區長度中。 加密文字必須 以小到尾 格式。

範例

如需使用此函式的範例,請參閱 範例 C 程式:解密檔案

規格需求

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

另請參閱

CryptCreateHash

CryptEncrypt

CryptGenKey

CryptGetHashParam

CryptGetKeyParam

CryptImportKey

CryptMsgOpenToEncode

CryptSignHash

CryptVerifySignature

資料加密/解密函式