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

如需 ALG_ID 值與 Microsoft 基底密碼編譯提供者搭配使用的詳細資訊,請參閱 基底提供者演算法。 如需 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 函式,將 dwParam 參數設定為 KP_SALT,來擷取此 salt 值。

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

匯出具有非零 salt 值的索引鍵時(使用 CryptExportKey),也必須取得 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 所產生。 下表列出一些可能的錯誤碼。

傳回碼 描述
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 輸入參數所代表的哈希值長度。 將緩衝區的第一個 k 個字節設定為 XOR 作業的結果,其中第一個 k 位元組的緩衝區,其哈希值是由輸入參數 hBaseData所表示。
  2. 藉由重複常數 0x5C 64 次,形成 64 位元組的緩衝區。 將緩衝區的第一個 k 個字節設定為 XOR 作業的結果,其中第一個 k 位元組的緩衝區,其哈希值是由輸入參數 hBaseData所表示。
  3. 使用與用來計算 hBaseData 參數所表示之哈希值相同的哈希演算法,哈希步驟 1 的結果。
  4. 使用與用來計算 hBaseData 參數所表示之哈希值相同的哈希演算法,哈希步驟 2 的結果。
  5. 將步驟 3 的結果與步驟 4 的結果串連。
  6. 使用步驟 5 結果的第一個 n 個字節作為衍生密鑰。
默認 RSA 完整密碼編譯服務提供者是Microsoft RSA 強式密碼編譯提供者。 默認 DSS 簽章 Diffie-Hellman 密碼編譯服務提供者是Microsoft增強型 DSS Diffie-Hellman 密碼編譯提供者。 這些 CSP 都有預設的 128 位對稱金鑰長度,適用於 RC2 和 RC4。

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

供應商 演算法 金鑰長度下限 預設金鑰長度 金鑰長度上限
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 強式 RC4 和 RC2 40 128 128
MS 強式 DES 56 56 56
MS 強式 3DES 112 112 112 112
MS 強式 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 [僅限傳統型應用程式]
目標平臺 窗戶
標頭 wincrypt.h
連結庫 Advapi32.lib
DLL Advapi32.dll

另請參閱

CryptAcquireContext

CryptCreateHash

CryptDestroyHash

CryptDestroyKey

CryptExportKey

CryptGenKey

CryptGetKeyParam

CryptHashData

CryptHashSessionKey

CryptSetKeyParam

金鑰產生和 Exchange 函式