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。
如需 ALG_ID 值與 Microsoft 基底密碼編譯提供者搭配使用的詳細資訊,請參閱 基底提供者演算法。 如需 ALG_ID 值與Microsoft強式密碼編譯提供者或Microsoft增強式密碼編譯提供者搭配使用的詳細資訊,請參閱 增強型提供者演算法。
[in] hBaseData
哈希物件的句柄, 已饋送確切的基底數據。
若要取得此句柄,應用程式必須先建立具有
[in] dwFlags
指定產生的金鑰類型。
產生金鑰時,可以設定會話金鑰的大小。 代表位中索引鍵模數長度的索引鍵大小,是以此參數的上16位設定。 因此,如果要產生 128 位 RC4 會話索引鍵,則值0x00800000會與任何其他 dwFlags 結合 具有位OR 作業的預先定義值。 由於變更匯出控制限制,預設 CSP 和預設 金鑰長度 可能會在作業系統版本之間變更。 加密和解密都必須使用相同的 CSP,以及使用 dwFlags 參數明確設定密鑰長度,以確保不同作業系統平臺上的互操作性。
此參數的下層 16 位可以是零,或者您可以使用位OR 運算符來指定下列一或多個旗標。
價值 | 意義 |
---|---|
|
一般而言,從 哈希 值建立會話密鑰時,會有一些剩餘位。 例如,如果哈希值是 128 位,而會話索引鍵為 40 位,則會保留 88 位。
如果設定此旗標,則會根據未使用的哈希值位,將索引鍵指派 salt 值。 您可以使用 CryptGetKeyParam 函式,將 dwParam 參數設定為 KP_SALT,來擷取此 salt 值。 如果未設定此旗標,則會為索引鍵指定為零的 salt 值。 匯出具有非零 salt 值的索引鍵時(使用 CryptExportKey),也必須取得 salt 值,並保留 密鑰 BLOB。 |
|
如果設定此旗標,會話密鑰可以透過 CryptExportKey 函式,從 CSP 移出至密鑰 BLOB。 因為索引鍵通常必須可匯出,因此通常應該設定此旗標。
如果未設定此旗標,則無法匯出會話金鑰。 這表示金鑰只能在目前的會話內使用,而且只有建立金鑰的應用程式才能使用它。 此旗標不適用於 |
|
此旗標會指定不會為 40 位 對稱金鑰配置任何 salt 值。 如需詳細資訊,請參閱 Salt 值功能。 |
|
某些 CSP 會使用衍生自多個哈希值的會話密鑰。 在此情況下,CryptDeriveKey 必須多次呼叫。
如果設定此旗標,則不會產生新的會話金鑰。 相反地,會修改 phKey 指定的索引鍵。 此旗標的精確行為取決於所產生密鑰的類型,以及所使用的特定 CSP。 Microsoft密碼編譯服務提供者忽略此旗標。 |
|
這個旗標只能與 通道 提供者搭配使用。 如果設定此旗標,則要產生的金鑰是伺服器寫入金鑰;否則,它是用戶端寫入密鑰。 |
[in, out] phKey
HCRYPTKEY 的指標 變數,以接收新產生的金鑰句柄位址。 當您完成使用密鑰時,請呼叫 CryptDestroyKey 函式來釋放句柄。
傳回值
如果函式成功,函式會傳回非零 (TRUE)。
如果函式失敗,則會傳回零 (FALSE)。 如需擴充錯誤資訊,請呼叫 getLastError
以 「NTE」 開頭的錯誤碼是由所使用的特定 CSP 所產生。 下表列出一些可能的錯誤碼。
傳回碼 | 描述 |
---|---|
|
其中一個參數指定無效的句柄。 |
|
其中一個參數包含無效的值。 這通常是無效的指標。 |
|
Algid 參數會指定此 CSP 不支持的演算法。 |
|
dwFlags 參數包含無效的值。 |
|
hBaseData 參數不包含 哈希物件的有效句柄。 |
|
嘗試將數據新增至已標示為「已完成」的哈希物件。 |
|
hProv 參數不包含有效的內容句柄。 |
|
函式以某種非預期的方式失敗。 |
|
提供者無法執行動作,因為內容是以無訊息方式取得。 |
言論
當 對稱區塊加密產生密鑰時,密鑰默認會設定為 加密區塊鏈結 (CBC) 模式,且初始化向量為零。 此 加密模式 提供大量加密數據的良好預設方法。 若要變更這些參數,請使用 CryptSetKeyParam 函式。
CryptDeriveKey 函式會完成 哈希。 呼叫 cryptDeriveKey
若要選擇適當的 金鑰長度,建議使用下列方法。
- 若要列舉 CSP 支援的演算法,並取得每個演算法的最大和最小密鑰長度,請使用 PP_ENUMALGS_EX 呼叫 cryptGetProvParam
。 - 使用最小和最大長度來選擇適當的密鑰長度。 不建議選擇最大長度,因為這可能會導致效能問題。
- 選擇所需的金鑰長度之後,請使用 dwFlags 參數的上方 16 位來指定金鑰長度。
- 藉由重複常數 0x36 64 次,形成 64 位元組的緩衝區。 讓 k 為 hBaseData 輸入參數所代表的哈希值長度。 將緩衝區的第一個 k 個字節設定為 XOR 作業的結果,其中第一個 k 位元組的緩衝區,其哈希值是由輸入參數 hBaseData所表示。
- 藉由重複常數 0x5C 64 次,形成 64 位元組的緩衝區。 將緩衝區的第一個 k 個字節設定為 XOR 作業的結果,其中第一個 k 位元組的緩衝區,其哈希值是由輸入參數 hBaseData所表示。
- 使用與用來計算 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 強式 | 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 |