共用方式為


CryptGenKey 函式 (wincrypt.h)

重要 此 API 已被取代。 新的和現有的軟體應該開始使用 密碼編譯新一代 API。 Microsoft 在未來版本中可能會移除此 API。
 
CryptGenKey 函式會產生隨機密碼編譯 會話密鑰公開/私鑰組。 在 phKey 中,會傳回金鑰或金鑰組的句柄。 然後,此句柄可以視需要與任何需要密鑰句柄的 CryptoAPI 函式搭配使用。

呼叫端應用程式必須在呼叫此函式時指定演算法。 由於此演算法類型會與金鑰一起保留,因此應用程式不需要稍後在執行實際的密碼編譯作業時指定演算法。

語法

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

參數

[in] hProv

呼叫 cryptAcquireContext所建立之 密碼編譯服務提供者 (CSP) 的句柄。

[in] Algid

ALG_ID 值,識別要產生金鑰的演算法。 此參數的值會根據所使用的 CSP 而有所不同。

如需與 Microsoft 基底密碼編譯提供者搭配使用的 ALG_ID 值,請參閱 基底提供者演算法

如需與Microsoft強式密碼編譯提供者或Microsoft增強式密碼編譯提供者搭配使用的 ALG_ID 值,請參閱 增強型提供者演算法

針對 Diffie-Hellman CSP,請使用下列其中一個值。

價值 意義
CALG_DH_EPHEM
指定索引鍵 Diffie-Hellman「暫時」。
CALG_DH_SF
指定金鑰 Diffie-Hellman「儲存和轉寄」。
 

除了為對稱演算法產生會話密鑰之外,此函式也可以產生 公用/私鑰組。 每個 CryptoAPI 用戶端通常會擁有兩個公開/私鑰組。 若要產生下列其中一個密鑰組,請將 Algid 參數設定為下列其中一個值。

價值 意義
AT_KEYEXCHANGE
金鑰交換
AT_SIGNATURE
數字簽名
 
注意 指定金鑰規格AT_KEYEXCHANGE和AT_SIGNATURE時,用來產生密鑰的演演算法識別碼取決於所使用的提供者。 因此,針對這些索引鍵規格,從 cryptGetKeyParam 傳回的值(指定KP_ALGID參數時)取決於所使用的提供者。 若要判斷金鑰規格AT_KEYEXCHANGE和AT_SIGNATURE之不同提供者所使用的演算法識別碼,請參閱 ALG_ID
 

[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 位可以是零或下列一或多個值的組合。

價值 意義
CRYPT_ARCHIVABLE
如果設定此旗標,則可以匯出索引鍵,直到呼叫 CryptDestroyKey關閉其句柄為止。 這可讓新產生的金鑰在建立時匯出以進行封存或密鑰復原。 關閉句柄之後,金鑰就無法再匯出。
CRYPT_CREATE_IV
未使用這個旗標。
CRYPT_CREATE_SALT
如果設定此旗標,則會自動將索引鍵指派隨機 salt 值。 您可以使用 CryptGetKeyParam 函式,將 dwParam 參數設定為 KP_SALT,來擷取這個 salt 值。

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

匯出具有非零 salt 值的索引鍵時(透過 cryptExportKey),則也必須取得並保留 密鑰 BLOBsalt 值。

CRYPT_DATA_KEY
未使用這個旗標。
CRYPT_EXPORTABLE
如果設定此旗標,則可以使用 CryptExportKey 函式,將密鑰從 CSP 移出至金鑰 BLOB。 因為會話金鑰通常必須可匯出,所以建立時通常應該設定此旗標。

如果未設定此旗標,則無法匯出索引鍵。 對於會話金鑰,這表示金鑰只能在目前的會話內使用,而且只有建立密鑰的應用程式才能使用它。 對於 公開/私鑰組,這表示無法傳輸或備份私鑰。

此旗標僅適用於工作階段金鑰和 私密金鑰 BLOB。 它不適用於一律可導出的公鑰。

CRYPT_FORCE_KEY_PROTECTION_HIGH
此旗標會指定強式密鑰保護。 設定此旗標時,系統會提示使用者在建立金鑰時輸入金鑰的密碼。 每當使用此金鑰時,系統會提示使用者輸入密碼。

此旗標僅供Microsoft提供的 CSP 使用。 第三方 CSP 會定義自己的行為,以進行強式密鑰保護。

指定此旗標會導致在系統登錄中指定強密鑰保護時,使用 CRYPT_USER_PROTECTED 旗標呼叫此函式時,產生相同的結果。

如果指定這個旗標,而且使用 CRYPT_VERIFYCONTEXTCRYPT_SILENT 旗標建立 hProv 參數中的提供者句柄,則此函式會將最後一個錯誤設定為 NTE_SILENT_CONTEXT 並傳回零。

Windows Server 2003 和 Windows XP:不支援此旗標。

CRYPT_KEK
未使用這個旗標。
CRYPT_INITIATOR
未使用這個旗標。
CRYPT_NO_SALT
此旗標會指定未設定任何 salt 值, 設定給 40 位 對稱金鑰。 如需詳細資訊,請參閱 Salt 值功能
CRYPT_ONLINE
未使用這個旗標。
CRYPT_PREGEN
此旗標會指定初始 Diffie-Hellman 或 DSS 金鑰產生。 此旗標僅適用於 Diffie-Hellman 和 DSS CSP。 使用時,除非在 dwFlags 參數的上方 16 位指定密鑰長度,否則會使用預設密鑰長度。 如果使用 CryptSetKeyParam,在 PREGEN Diffie-Hellman 或 DSS 金鑰上設定涉及金鑰長度的參數,密鑰長度必須與此處設定的金鑰長度相容。
CRYPT_RECIPIENT
未使用這個旗標。
CRYPT_SF
未使用這個旗標。
CRYPT_SGCKEY
未使用這個旗標。
CRYPT_USER_PROTECTED
如果設定此旗標,當用戶嘗試使用此金鑰時,會透過對話方塊或其他方法通知使用者。 所使用 CSP 會指定精確的行為。 如果提供者內容是以已設定CRYPT_SILENT旗標開啟,則使用此旗標會導致失敗,而最後一個錯誤會設定為NTE_SILENT_CONTEXT。
CRYPT_VOLATILE
未使用這個旗標。

[out] phKey

函式複製新產生索引鍵句柄的位址。 當您完成使用金鑰時,請呼叫 CryptDestroyKey 函式來刪除密鑰的句柄。

傳回值

如果成功或零,則傳回非零。

如需擴充錯誤資訊,請呼叫 getLastError

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

傳回碼 描述
ERROR_INVALID_HANDLE
其中一個參數指定無效的句柄。
ERROR_INVALID_PARAMETER
其中一個參數包含無效的值。 這通常是無效的指標。
NTE_BAD_ALGID
Algid 參數會指定此 CSP 不支持的演算法。
NTE_BAD_FLAGS
dwFlags 參數包含無效的值。
NTE_BAD_UID
hProv 參數不包含有效的內容句柄。
NTE_FAIL
函式以某種非預期的方式失敗。
NTE_SILENT_CONTEXT
提供者無法執行動作,因為內容是以無訊息方式取得。

言論

如果為 對稱區塊加密產生密鑰,則密鑰預設會設定為 加密區塊鏈結 (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

另請參閱

CryptAcquireContext

CryptDestroyKey

CryptExportKey

CryptGetKeyParam

CryptImportKey

CryptSetKeyParam

金鑰產生和 Exchange 函式

密碼編譯服務提供者的線程問題