CryptDeriveKey 函式 (wincrypt.h)
此函式與 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 運算符來合併它們,來指定下列一或多個旗標。
值 | 意義 |
---|---|
|
一般而言,從 哈希 值建立會話索引鍵時,會有一些剩餘位。 例如,如果哈希值為128位,而會話密鑰為40位,則剩餘88位。
如果已設定此旗標,則會根據未使用的哈希值位,將索引鍵指派為 salt 值。 您可以使用 CryptGetKeyParam 函式來擷取此 salt 值,並將 dwParam 參數設定為 KP_SALT。 如果未設定此旗標,則會將索引鍵指定為零的 salt 值。 使用 CryptExportKey) 匯出具有非零 salt 值的索引鍵 (時,也必須取得 salt 值,並與 密鑰 BLOB 一起保留。 |
|
如果設定此旗標,會話密鑰可以透過 CryptExportKey 函式,將會話密鑰從 CSP 傳輸至金鑰 BLOB。 由於索引鍵通常必須可匯出,因此通常應該設定此旗標。
如果未設定此旗標,則無法匯出會話金鑰。 這表示金鑰只能在目前的會話內使用,而且只有建立金鑰的應用程式能夠使用它。 此旗標不適用於 公開/私鑰組。 |
|
此旗標指定不會為40位對稱金鑰配置任何 salt 值。 如需詳細資訊,請參閱 Salt 值功能。 |
|
某些 CSP 會使用衍生自多個哈希值的會話密鑰。 在此情況下,必須多次呼叫 CryptDeriveKey 。
如果設定此旗標,則不會產生新的會話金鑰。 相反地, 會修改 phKey 所指定的金鑰。 此旗標的精確行為取決於所產生密鑰的類型,以及所使用的特定 CSP。 Microsoft 密碼編譯服務提供者會忽略此旗標。 |
|
此旗標僅與 安全通道 提供者搭配使用。 如果設定此旗標,則產生的金鑰是伺服器寫入金鑰;否則,它是用戶端寫入密鑰。 |
[in, out] phKey
要接收新產生之密鑰句柄之 HCRYPTKEY 變數的指標。 當您完成使用密鑰時,請呼叫 CryptDestroyKey 函式來釋放句柄。
傳回值
如果函式成功,函式會傳回非零 (TRUE) 。
如果函式失敗,它會傳回零 (FALSE) 。 如需擴充的錯誤資訊,請呼叫 GetLastError。
開頭為 「NTE」 的錯誤碼是由所使用的特定 CSP 所產生。 下表列出一些可能的錯誤碼。
傳回碼 | Description |
---|---|
|
其中一個參數指定無效的句柄。 |
|
其中一個參數包含無效的值。 這通常是無效的指標。 |
|
Algid 參數會指定此 CSP 不支持的演算法。 |
|
dwFlags 參數包含無效的值。 |
|
hBaseData 參數不包含哈希物件的有效句柄。 |
|
嘗試將數據新增至已標示為「已完成」的哈希物件。 |
|
hProv 參數不包含有效的內容句柄。 |
|
函式會以非預期的方式失敗。 |
|
提供者無法執行動作,因為內容是以無訊息方式取得。 |
備註
為 對稱區塊加密產生密鑰時,預設會將密鑰設定為加密 區塊鏈結 (CBC) 模式,其初始化向量為零。 此 加密模式 提供大量加密數據的良好預設方法。 若要變更這些參數,請使用 CryptSetKeyParam 函式。
CryptDeriveKey 函式會完成哈希。 呼叫 CryptDeriveKey 之後,就無法再將數據新增至哈希。 對 CryptHashData 或 CryptHashSessionKey 的其他呼叫失敗。 使用哈希完成應用程式之後,必須呼叫 CryptDestroyHash 以終結哈希物件。
若要選擇適當的 密鑰長度,建議使用下列方法。
- 若要列舉 CSP 支援的演算法,並取得每個演算法的最大和最小密鑰長度,請使用 PP_ENUMALGS_EX 呼叫 CryptGetProvParam 。
- 使用最小和最大長度來選擇適當的密鑰長度。 不一定建議選擇最大長度,因為這可能會導致效能問題。
- 選擇所需的金鑰長度之後,請使用 dwFlags 參數的上限 16 位來指定金鑰長度。
- 重複常數 0x36 64 次,以形成 64 位元組的緩衝區。 讓 k 成為輸入參數 hBaseData 所代表之哈希值的長度。 使用輸入參數 hBaseData 所代表的哈希值,將緩衝區的第一個 k 個字節的 XOR 作業結果設定為緩衝區的第一個 K 位元組。
- 重複常數 0x5C 64 次,以形成 64 位元組的緩衝區。 使用輸入參數 hBaseData 所代表的哈希值,將緩衝區的第一個 k 個字節的 XOR 作業結果設定為緩衝區的第一個 K 位元組。
- 使用與用來計算 hBaseData 參數所表示哈希值相同的哈希演算法,哈希步驟 1 的結果。
- 使用與用來計算 hBaseData 參數所表示哈希值的哈希值相同的哈希演算法,哈希步驟 2 的結果。
- 將步驟 3 的結果與步驟 4 的結果串連。
- 使用步驟 5 結果的前 n 個字節做為衍生索引鍵。
下表列出演算法和提供者的會話密鑰最小、預設和最大密鑰長度。
提供者 | 演算法 | 最小金鑰長度 | 預設金鑰長度 | 金鑰長度上限 |
---|---|---|---|---|
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 |
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應