CryptGenKey 函式 (wincrypt.h)
呼叫端應用程式必須在呼叫此函式時指定演算法。 由於此演算法類型會與金鑰一起保留,因此應用程式不需要稍後在執行實際的密碼編譯作業時指定演算法。
語法
BOOL CryptGenKey(
[in] HCRYPTPROV hProv,
[in] ALG_ID Algid,
[in] DWORD dwFlags,
[out] HCRYPTKEY *phKey
);
參數
[in] hProv
呼叫 cryptAcquireContext所建立之
[in] Algid
ALG_ID 值,識別要產生金鑰的演算法。 此參數的值會根據所使用的 CSP 而有所不同。
如需與 Microsoft 基底密碼編譯提供者搭配使用的 ALG_ID 值,請參閱 基底提供者演算法。
如需與Microsoft強式密碼編譯提供者或Microsoft增強式密碼編譯提供者搭配使用的 ALG_ID 值,請參閱 增強型提供者演算法。
針對 Diffie-Hellman CSP,請使用下列其中一個值。
價值 | 意義 |
---|---|
|
指定索引鍵 Diffie-Hellman「暫時」。 |
|
指定金鑰 Diffie-Hellman「儲存和轉寄」。 |
除了為
價值 | 意義 |
---|---|
|
金鑰交換 |
|
數字簽名 |
[in] dwFlags
指定產生的金鑰類型。 會話金鑰、RSA 簽章金鑰和 RSA 金鑰的大小 交換金鑰 可以在產生金鑰時設定。 代表位中索引鍵模數長度的索引鍵大小,是以此參數的上16位設定。 因此,如果要產生 2,048 位 RSA 簽章密鑰,則值0x08000000會與任何其他 dwFlags 結合, 具有位OR 作業的預先定義值。 0x08000000的16位是0x0800,或十進位2,048。 RSA1024BIT_KEY 值可用來指定 1024 位 RSA 金鑰。
由於變更匯出控制限制,預設 CSP 和預設 金鑰長度 可能會在作業系統版本之間變更。 加密和解密都必須使用相同的 CSP,以及使用 dwFlags 參數明確設定密鑰長度,以確保不同作業系統平臺上的互操作性。
特別是,預設 RSA 完整密碼編譯服務提供者是Microsoft RSA 強式密碼編譯提供者。 默認 DSS 簽章 Diffie-Hellman 密碼編譯服務提供者是Microsoft增強型 DSS Diffie-Hellman 密碼編譯提供者。 這些 CSP 都有 RC2 和 RC4 的預設 128 位對稱密鑰長度,以及公鑰演演算法的 1,024 位預設密鑰長度。
如果前16位為零,則會產生預設金鑰大小。 如果指定的索引鍵大於最大值或小於最小值,則呼叫會因為ERROR_INVALID_PARAMETER程式代碼而失敗。
下表列出以 Windows XP 開頭的最小、預設和最大簽章和交換密鑰長度。
金鑰類型和提供者 | 最小長度 | 默認長度 | 最大長度 |
---|---|---|---|
RSA 基底提供者 Signature 和 ExchangeKeys |
384 | 512 | 16,384 |
RSA 強式和增強型提供者 簽章和交換金鑰 |
384 | 1,024 | 16,384 |
DSS 基底提供者 簽章金鑰 |
512 | 1,024 | 1,024 |
DSS 基底提供者 Exchange 金鑰 |
不適用 | 不適用 | 不適用 |
DSS/DH 基底提供者 簽章金鑰 |
512 | 1,024 | 1,024 |
DSS/DH 基底提供者 Exchange 金鑰 |
512 | 512 | 1,024 |
DSS/DH 增強型提供者 簽章金鑰 |
512 | 1,024 | 1,024 |
DSS/DH 增強型提供者 Exchange 金鑰 |
512 | 1,024 | 4,096 |
如需工作階段金鑰長度,請參閱 CryptDeriveKey。
如需使用 Microsoft 提供者產生之金鑰的詳細資訊,請參閱 Microsoft 密碼編譯服務提供者。
此參數的下層 16 位可以是零或下列一或多個值的組合。
價值 | 意義 |
---|---|
|
如果設定此旗標,則可以匯出索引鍵,直到呼叫 CryptDestroyKey關閉其句柄為止。 這可讓新產生的金鑰在建立時匯出以進行封存或密鑰復原。 關閉句柄之後,金鑰就無法再匯出。 |
|
未使用這個旗標。 |
|
如果設定此旗標,則會自動將索引鍵指派隨機 salt 值。 您可以使用 CryptGetKeyParam 函式,將 dwParam 參數設定為 KP_SALT,來擷取這個 salt 值。
如果未設定此旗標,則會為索引鍵指定為零的 salt 值。 匯出具有非零 salt 值的索引鍵時(透過 cryptExportKey |
|
未使用這個旗標。 |
|
如果設定此旗標,則可以使用 CryptExportKey 函式,將密鑰從 CSP 移出至金鑰 BLOB。 因為會話金鑰通常必須可匯出,所以建立時通常應該設定此旗標。
如果未設定此旗標,則無法匯出索引鍵。 對於會話金鑰,這表示金鑰只能在目前的會話內使用,而且只有建立密鑰的應用程式才能使用它。 對於 公開/私鑰組,這表示無法傳輸或備份私鑰。 此旗標僅適用於工作階段金鑰和 私密金鑰 BLOB。 它不適用於一律可導出的公鑰。 |
|
此旗標會指定強式密鑰保護。 設定此旗標時,系統會提示使用者在建立金鑰時輸入金鑰的密碼。 每當使用此金鑰時,系統會提示使用者輸入密碼。
此旗標僅供Microsoft提供的 CSP 使用。 第三方 CSP 會定義自己的行為,以進行強式密鑰保護。 指定此旗標會導致在系統登錄中指定強密鑰保護時,使用 CRYPT_USER_PROTECTED 旗標呼叫此函式時,產生相同的結果。 如果指定這個旗標,而且使用 CRYPT_VERIFYCONTEXT 或 CRYPT_SILENT 旗標建立 hProv 參數中的提供者句柄,則此函式會將最後一個錯誤設定為 NTE_SILENT_CONTEXT 並傳回零。 Windows Server 2003 和 Windows XP:不支援此旗標。 |
|
未使用這個旗標。 |
|
未使用這個旗標。 |
|
此旗標會指定未設定任何 salt 值, 設定給 40 位 對稱金鑰。 如需詳細資訊,請參閱 Salt 值功能。 |
|
未使用這個旗標。 |
|
此旗標會指定初始 Diffie-Hellman 或 DSS 金鑰產生。 此旗標僅適用於 Diffie-Hellman 和 DSS CSP。 使用時,除非在 dwFlags 參數的上方 16 位指定密鑰長度,否則會使用預設密鑰長度。 如果使用 CryptSetKeyParam,在 PREGEN Diffie-Hellman 或 DSS 金鑰上設定涉及金鑰長度的參數,密鑰長度必須與此處設定的金鑰長度相容。 |
|
未使用這個旗標。 |
|
未使用這個旗標。 |
|
未使用這個旗標。 |
|
如果設定此旗標,當用戶嘗試使用此金鑰時,會透過對話方塊或其他方法通知使用者。 所使用 CSP 會指定精確的行為。 如果提供者內容是以已設定CRYPT_SILENT旗標開啟,則使用此旗標會導致失敗,而最後一個錯誤會設定為NTE_SILENT_CONTEXT。 |
|
未使用這個旗標。 |
[out] phKey
函式複製新產生索引鍵句柄的位址。 當您完成使用金鑰時,請呼叫 CryptDestroyKey 函式來刪除密鑰的句柄。
傳回值
如果成功或零,則傳回非零。
如需擴充錯誤資訊,請呼叫 getLastError
以 「NTE」 開頭的錯誤碼是由所使用的特定 CSP 所產生。 下表列出一些可能的錯誤碼。
傳回碼 | 描述 |
---|---|
|
其中一個參數指定無效的句柄。 |
|
其中一個參數包含無效的值。 這通常是無效的指標。 |
|
Algid 參數會指定此 CSP 不支持的演算法。 |
|
dwFlags 參數包含無效的值。 |
|
hProv 參數不包含有效的內容句柄。 |
|
函式以某種非預期的方式失敗。 |
|
提供者無法執行動作,因為內容是以無訊息方式取得。 |
言論
如果為 對稱區塊加密產生密鑰,則密鑰預設會設定為 加密區塊鏈結 (CBC) 模式,且初始化向量為零。 此 加密模式 提供大量加密數據的良好預設方法。 若要變更這些參數,請使用 CryptSetKeyParam 函式。
若要選擇適當的 金鑰長度,建議使用下列方法:
- 列舉 CSP 支援的演算法,並取得每個演算法的最大和最小密鑰長度。 若要這樣做,請使用 PP_ENUMALGS_EX 呼叫 cryptGetProvParam
。 - 使用最小和最大長度來選擇適當的密鑰長度。 不建議選擇最大長度,因為這可能會導致效能問題。
- 選擇所需的金鑰長度之後,請使用 dwFlags 參數的上方 16 位來指定金鑰長度。
例子
下列範例示範如何建立隨機會話密鑰。 如需包含此範例完整內容的範例,請參閱 範例 C 程式:加密檔案。 如需使用此函式的另一個範例,請參閱 範例 C 程式:解密檔案。
//-------------------------------------------------------------------
// Declare the handle to the key.
HCRYPTKEY hKey;
//-------------------------------------------------------------------
// This example assumes that a cryptographic context
// has been acquired, and that it is stored in hCryptProv.
//---------------------------------------------------------------
// Create a random session key.
if(CryptGenKey(
hCryptProv,
ENCRYPT_ALGORITHM,
KEYLENGTH | CRYPT_EXPORTABLE,
&hKey))
{
printf("A session key has been created.\n");
}
else
{
printf("Error during CryptGenKey.\n");
exit(1);
}
//-------------------------------------------------------------------
// The key created can be exported into a key BLOB that can be
// written to a file.
// ...
// When you have finished using the key, free the resource.
if (!CryptDestroyKey(hKey))
{
printf("Error during CryptDestroyKey.\n");
exit(1);
}
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | Windows XP [僅限傳統型應用程式] |
支援的最低伺服器 | Windows Server 2003 [僅限傳統型應用程式] |
目標平臺 | 窗戶 |
標頭 | wincrypt.h |
連結庫 | Advapi32.lib |
DLL | Advapi32.dll |