CryptDeriveKey 函式 (wincrypt.h)

重要 此 API 已被取代。 新的和現有的軟體應該開始使用 密碼編譯新一代 API。 Microsoft 可能會在未來的版本中移除此 API。
 
CryptDeriveKey 函式會產生衍生自基底數據值的密碼編譯會話密鑰。 此函式可確保使用相同的 密碼編譯服務提供者 (CSP) 和演算法時,從相同基底數據產生的密鑰相同。 基底數據可以是密碼或任何其他用戶數據。

此函式與 CryptGenKey 相同,不同之處在於產生的 會話密鑰 衍生自基底數據,而不是隨機的。 CryptDeriveKey 只能用來產生會話密鑰。 它無法產生 公開/私鑰組

會話金鑰的句柄會在 phKey 參數中傳回。 此句柄可以搭配任何需要密鑰句柄的 CryptoAPI 函式使用。

語法

BOOL CryptDeriveKey(
  [in]      HCRYPTPROV hProv,
  [in]      ALG_ID     Algid,
  [in]      HCRYPTHASH hBaseData,
  [in]      DWORD      dwFlags,
  [in, out] HCRYPTKEY  *phKey
);

參數

[in] hProv

呼叫 CryptAcquireContext 所建立 CSP 的 HCRYPTPROV 句柄。

[in] Algid

ALG_ID結構,識別要為其產生密鑰的對稱加密演算法。 每個 CSP 可用的演算法很可能不同。 如需不同提供者針對密鑰規格AT_KEYEXCHANGE和AT_SIGNATURE使用哪些演算法識別碼的詳細資訊,請參閱 ALG_ID

如需與 Microsoft 基底密碼編譯提供者搭配使用 ALG_ID 值的詳細資訊,請參閱 基底提供者演算法。 如需 ALG_ID值與 Microsoft 強式密碼編譯提供者或 Microsoft 增強式密碼編譯提供者搭配使用的詳細資訊,請參閱 增強提供者演算法

[in] hBaseData

已饋送確切基底數據的 哈希物件的 句柄。

若要取得此句柄,應用程式必須先使用 CryptCreateHash 建立哈希對象,然後使用 CryptHashData 將基底數據新增至哈希物件。 此程式會在 哈希和數位簽名中詳細說明。

[in] dwFlags

指定產生的金鑰類型。

產生金鑰時,可以設定會話金鑰的大小。 代表位中金鑰模數長度的金鑰大小,會以此參數的上限 16 位來設定。 因此,如果要產生 128 位 RC4 工作階段金鑰,則值0x00800000會與任何其他 dwFlags 預先定義值與位 OR 運算結合。 由於變更匯出控制限制,預設 CSP 和預設 金鑰長度 可能會在作業系統版本之間變更。 加密和解密都必須使用相同的 CSP,並使用 dwFlags 參數明確設定密鑰長度,以確保不同作業系統平臺上的互操作性。

此參數的下層 16 位可以是零,或者您可以使用位 OR 運算符來合併它們,來指定下列一或多個旗標。

意義
CRYPT_CREATE_SALT
一般而言,從 哈希 值建立會話索引鍵時,會有一些剩餘位。 例如,如果哈希值為128位,而會話密鑰為40位,則剩餘88位。

如果已設定此旗標,則會根據未使用的哈希值位,將索引鍵指派為 salt 值。 您可以使用 CryptGetKeyParam 函式來擷取此 salt 值,並將 dwParam 參數設定為 KP_SALT。

如果未設定此旗標,則會將索引鍵指定為零的 salt 值。

使用 CryptExportKey) 匯出具有非零 salt 值的索引鍵 (時,也必須取得 salt 值,並與 密鑰 BLOB 一起保留。

CRYPT_EXPORTABLE
如果設定此旗標,會話密鑰可以透過 CryptExportKey 函式,將會話密鑰從 CSP 傳輸至金鑰 BLOB。 由於索引鍵通常必須可匯出,因此通常應該設定此旗標。

如果未設定此旗標,則無法匯出會話金鑰。 這表示金鑰只能在目前的會話內使用,而且只有建立金鑰的應用程式能夠使用它。

此旗標不適用於 公開/私鑰組

CRYPT_NO_SALT
此旗標指定不會為40位對稱金鑰配置任何 salt 值。 如需詳細資訊,請參閱 Salt 值功能
CRYPT_UPDATE_KEY
某些 CSP 會使用衍生自多個哈希值的會話密鑰。 在此情況下,必須多次呼叫 CryptDeriveKey

如果設定此旗標,則不會產生新的會話金鑰。 相反地, 會修改 phKey 所指定的金鑰。 此旗標的精確行為取決於所產生密鑰的類型,以及所使用的特定 CSP。

Microsoft 密碼編譯服務提供者會忽略此旗標。

CRYPT_SERVER
1024 (0x400)
此旗標僅與 安全通道 提供者搭配使用。 如果設定此旗標,則產生的金鑰是伺服器寫入金鑰;否則,它是用戶端寫入密鑰。

[in, out] phKey

要接收新產生之密鑰句柄之 HCRYPTKEY 變數的指標。 當您完成使用密鑰時,請呼叫 CryptDestroyKey 函式來釋放句柄。

傳回值

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

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

開頭為 「NTE」 的錯誤碼是由所使用的特定 CSP 所產生。 下表列出一些可能的錯誤碼。

傳回碼 Description
ERROR_INVALID_HANDLE
其中一個參數指定無效的句柄。
ERROR_INVALID_PARAMETER
其中一個參數包含無效的值。 這通常是無效的指標。
NTE_BAD_ALGID
Algid 參數會指定此 CSP 不支持的演算法。
NTE_BAD_FLAGS
dwFlags 參數包含無效的值。
NTE_BAD_HASH
hBaseData 參數不包含哈希物件的有效句柄。
NTE_BAD_HASH_STATE
嘗試將數據新增至已標示為「已完成」的哈希物件。
NTE_BAD_UID
hProv 參數不包含有效的內容句柄。
NTE_FAIL
函式會以非預期的方式失敗。
NTE_SILENT_CONTEXT
提供者無法執行動作,因為內容是以無訊息方式取得。

備註

對稱區塊加密產生密鑰時,預設會將密鑰設定為加密 區塊鏈結 (CBC) 模式,其初始化向量為零。 此 加密模式 提供大量加密數據的良好預設方法。 若要變更這些參數,請使用 CryptSetKeyParam 函式。

CryptDeriveKey 函式會完成哈希。 呼叫 CryptDeriveKey 之後,就無法再將數據新增至哈希。 對 CryptHashDataCryptHashSessionKey 的其他呼叫失敗。 使用哈希完成應用程式之後,必須呼叫 CryptDestroyHash 以終結哈希物件。

若要選擇適當的 密鑰長度,建議使用下列方法。

  • 若要列舉 CSP 支援的演算法,並取得每個演算法的最大和最小密鑰長度,請使用 PP_ENUMALGS_EX 呼叫 CryptGetProvParam
  • 使用最小和最大長度來選擇適當的密鑰長度。 不一定建議選擇最大長度,因為這可能會導致效能問題。
  • 選擇所需的金鑰長度之後,請使用 dwFlags 參數的上限 16 位來指定金鑰長度。
n 成為必要的衍生金鑰長度,以位元組為單位。 衍生索引鍵是 CryptDeriveKey 完成哈希計算之後,哈希值的前 n 個字節。 如果哈希不是 SHA-2 系列的成員,而且必要的密鑰適用於 3DES 或 AES,則會衍生密鑰,如下所示:
  1. 重複常數 0x36 64 次,以形成 64 位元組的緩衝區。 讓 k 成為輸入參數 hBaseData 所代表之哈希值的長度。 使用輸入參數 hBaseData 所代表的哈希值,將緩衝區的第一個 k 個字節的 XOR 作業結果設定為緩衝區的第一個 K 位元組。
  2. 重複常數 0x5C 64 次,以形成 64 位元組的緩衝區。 使用輸入參數 hBaseData 所代表的哈希值,將緩衝區的第一個 k 個字節的 XOR 作業結果設定為緩衝區的第一個 K 位元組。
  3. 使用與用來計算 hBaseData 參數所表示哈希值相同的哈希演算法,哈希步驟 1 的結果。
  4. 使用與用來計算 hBaseData 參數所表示哈希值的哈希值相同的哈希演算法,哈希步驟 2 的結果。
  5. 將步驟 3 的結果與步驟 4 的結果串連。
  6. 使用步驟 5 結果的前 n 個字節做為衍生索引鍵。
默認 RSA 完整密碼編譯服務提供者是 Microsoft RSA 強密碼編譯提供者。 默認 DSS 簽章 Diffie-Hellman 密碼編譯服務提供者是 Microsoft 增強型 DSS Diffie-Hellman 密碼編譯提供者。 這些 CSP 都有 RC2 和 RC4 的預設 128 位對稱密鑰長度。

下表列出演算法和提供者的會話密鑰最小、預設和最大密鑰長度。

提供者 演算法 最小金鑰長度 預設金鑰長度 金鑰長度上限
MS Base RC4 和 RC2 40 40 56
MS Base DES 56 56 56
MS Enhanced RC4 和 RC2 40 128 128
MS Enhanced DES 56 56 56
MS Enhanced 3DES 112 112 112 112
MS Enhanced 3DES 168 168 168
MS Strong RC4 和 RC2 40 128 128
MS Strong DES 56 56 56
MS Strong 3DES 112 112 112 112
MS Strong 3DES 168 168 168
DSS/DH 基底 RC4 和 RC2 40 40 56
DSS/DH 基底 Cylink MEK 40 40 40
DSS/DH 基底 DES 56 56 56
DSS/DH Enh RC4 和 RC2 40 128 128
DSS/DH Enh Cylink MEK 40 40 40
DSS/DH Enh DES 56 56 56
DSS/DH Enh 3DES 112 112 112 112
DSS/DH Enh 3DES 168 168 168
 

範例

如需使用此函式的範例,請參閱 範例 C 程式:從密碼衍生會話密鑰

規格需求

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

另請參閱

CryptAcquireContext

CryptCreateHash

CryptDestroyHash

CryptDestroyKey

CryptExportKey

CryptGenKey

CryptGetKeyParam

CryptHashData

CryptHashSessionKey

CryptSetKeyParam

金鑰產生和 Exchange 函式